<commit_before>var monzo = {
  // general
  name: "Monzo Account",
  provider: "monzo",

  // auth
  authType: "oauth2",
  accessToken: null,
  accessExpires: -1,
  // variables below used while auth is being negotiated
  clientId: null,
  clientSecret: null,
  state: null,
  redirectUri: null,

  // auth functions
  auth: function() {
    if (clientId == null) {
      throw new Error("clientId isn't set and yet auth was called!");
    }
    if (clientSecret == null) {
      throw new Error("clientSecret isn't set and yet auth was called!");
    }
    if (state == null) {
      throw new Error("state isn't set and yet auth was called!");
    }
    if (redirectUri == null) {
      throw new Error("redirectUri isn't set and yet auth was called!");
    }
    window.location = "https://auth.getmondo.co.uk/?client_id=" + this.clientId + "&redirect_uri=" + this.redirectUri + "&response_type=code&state=" + this.state;
  },

  callback: function(authCode, state) {
    if (clientId == null) {
      throw new Error("clientId isn't set and yet callback was called!");
    }
    if (clientSecret == null) {
      throw new Error("clientSecret isn't set and yet callback was called!");
    }
    if (state == null) {
      throw new Error("state isn't set and yet callback was called!");
    }
    if (redirectUri == null) {
      throw new Error("redirectUri isn't set and yet callback was called!");
    }

    var request = new XMLHttpRequest();
    request.open("POST", "https://api.monzo.com/oauth2/token", false);
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    request.send("grant_type=authorization_code&client_id=" + this.clientId + "&client_secret=" + this.clientSecret + "&redirect_uri=" + this.redirectUri + "&code=" + authCode);
    if (request.status == 200) {
      this.accessToken = JSON.parse(request.responseText).access_token;
      this.accessExpires = Date.now() + JSON.parse(request.responseText).expires_in * 1000;
      // clear the variables we were using while getting an access token
      this.clientId = null;
      this.clientSecret = null;
      this.redirectUri = null;
      this.state = null;
    }
  },

  // other variables
  accountId: null,
};

function getMonzo() {
  return monzo;
}<commit_msg>Added a few missing 'this'<commit_after>var monzo = {
  // general
  name: "Monzo Account",
  provider: "monzo",

  // auth
  authType: "oauth2",
  accessToken: null,
  accessExpires: -1,
  // variables below used while auth is being negotiated
  clientId: null,
  clientSecret: null,
  state: null,
  redirectUri: null,

  // auth functions
  auth: function() {
    if (this.clientId == null) {
      throw new Error("clientId isn't set and yet auth was called!");
    }
    if (this.clientSecret == null) {
      throw new Error("clientSecret isn't set and yet auth was called!");
    }
    if (this.state == null) {
      throw new Error("state isn't set and yet auth was called!");
    }
    if (this.redirectUri == null) {
      throw new Error("redirectUri isn't set and yet auth was called!");
    }
    window.location = "https://auth.getmondo.co.uk/?client_id=" + this.clientId + "&redirect_uri=" + this.redirectUri + "&response_type=code&state=" + this.state;
  },

  callback: function(authCode, state) {
    if (this.clientId == null) {
      throw new Error("clientId isn't set and yet callback was called!");
    }
    if (this.clientSecret == null) {
      throw new Error("clientSecret isn't set and yet callback was called!");
    }
    if (this.state == null) {
      throw new Error("state isn't set and yet callback was called!");
    }
    if (this.redirectUri == null) {
      throw new Error("redirectUri isn't set and yet callback was called!");
    }

    var request = new XMLHttpRequest();
    request.open("POST", "https://api.monzo.com/oauth2/token", false);
    request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    request.send("grant_type=authorization_code&client_id=" + this.clientId + "&client_secret=" + this.clientSecret + "&redirect_uri=" + this.redirectUri + "&code=" + authCode);
    if (request.status == 200) {
      this.accessToken = JSON.parse(request.responseText).access_token;
      this.accessExpires = Date.now() + JSON.parse(request.responseText).expires_in * 1000;
      // clear the variables we were using while getting an access token
      this.clientId = null;
      this.clientSecret = null;
      this.redirectUri = null;
      this.state = null;
    }
  },

  // other variables
  accountId: null,
};

function getMonzo() {
  return monzo;
}<|endoftext|>


<commit_before>/* global define: false */
define([
	'lodash',
	'vexflow',
	'app/util/analyze',
], function(_, Vex, Analyze) {
	"use strict";

	var StaveNotater = function(config) {
		this.init(config);
	};

	_.extend(StaveNotater.prototype, {
		init: function(config) {
			this.config = config;
			this.initConfig();
		},
		initConfig: function() {
			var required = ['chord', 'keySignature', 'clef', 'highlights'];
			_.each(required, function(propName) {
				if(this.config.hasOwnProperty(propName)) {
					this[propName] = this.config[propName];
				} else {
					throw new Error("missing required config property: "+propName);
				}
			}, this);
		},
		// returns true if there are any notes
		hasStaveNotes: function() {
			return this.chord.hasNotes(this.clef);
		},
		// returns a list of Vex.Flow stave notes
		getStaveNotes: function() {
			var note_struct = this._getNoteKeysAndModifiers();
			var stave_note = this._makeStaveNote(note_struct.keys, note_struct.modifiers);
			return [stave_note];
		},
		// returns a list of key names for this stave only ["note/octave", ...]
		_getNoteKeys: function() {
			var keySignature = this.keySignature;
			var clef = this.clef;
			var pitches = this.chord.getNotePitches(this.clef);
			var spelling = keySignature.getSpelling();
			var note, pitchClass, octave;
			var note_keys = [];

			for(var i = 0, len = pitches.length; i < len; i++) {
				pitchClass = pitches[i].pitchClass;
				octave = pitches[i].octave;
				note = spelling[pitchClass];
				octave = this.calculateOctave(pitchClass, octave, note);
				note_keys.push([note, octave].join('/'));
			}

			return note_keys;
		},
		// returns an array of objects containing each key and accidental
		_getAccidentalsOf: function(noteKeys) {
			var keySignature = this.keySignature;
			var accidentals = [];
			var accidental,
				note,
				note_spelling,
				natural_note,
				natural_found_idx,
				is_doubled;

			for(var i = 0, len = noteKeys.length; i < len; i++) {
				// skip to next iteration is for the case that the
				// note has already been assigned a natural because
				// the same note name appears twice (i.e. is doubled).
				if(accidentals[i]) {
					continue;
				}

				note = noteKeys[i];
				note_spelling = note.replace(/\/\d$/, '');
				accidental = note_spelling.substr(1); // get default accidental
				natural_note = note.replace(accidental + "\/", '/');
				natural_found_idx = noteKeys.indexOf(natural_note);
				is_doubled = natural_found_idx !== -1 && i !== natural_found_idx;

				// check to see if this note is doubled - that is, the natrual version of
				// the note is also active at the same time, in which case it needs to be
				// distinguished with a natural accidental
				if(is_doubled) {
					accidentals[natural_found_idx] = 'n';
				} else {
					// otherwise check the key signature to determine the accidental
					if(keySignature.signatureContains(note_spelling)) {
						accidental = '';
					} else if(keySignature.needsNatural(note_spelling)) {
						accidental = 'n';
					}
				}

				accidentals[i] = accidental;
			}

			return accidentals;
		},
		// returns the octave for a note, taking into account
		// the current note spelling
		calculateOctave: function(pitchClass, octave, note) {
			var note_letter = note.charAt(0);
			if(pitchClass === 0 && note_letter === 'B') {
				return octave - 1;
			} else if(pitchClass === 11 && note_letter === 'C') {
				return octave + 1;
			}
			return octave;
		},
		// returns a list of keys and associated modifiers for constructing Vex.Flow stave notes
		_getNoteKeysAndModifiers: function() {
			var keys = this._getNoteKeys();
			var accidentals = this._getAccidentalsOf(keys);
			var allMidiKeys = this.chord.getNoteNumbers(); // for highlights across stave boundaries
			var midiKeys = this.chord.getNoteNumbers(this.clef);
			var modifiers = [];

			for(var i = 0, len = keys.length; i < len; i++) {
				if(accidentals[i]) {
					modifiers.push(this._makeAccidentalModifier(i, accidentals[i]));
				}
				if(this.highlights.enabled) {
					modifiers.push(this._makeHighlightModifier(i, midiKeys[i], allMidiKeys));
				}
			}

			return {keys: keys, modifiers: modifiers};
		},
		// returns a function that will add an accidental to a Vex.Flow stave note
		_makeAccidentalModifier: function(keyIndex, accidental) {
			return function(staveNote) {
				staveNote.addAccidental(keyIndex, new Vex.Flow.Accidental(accidental));
			};
		},
		_makeHighlightModifier: function(keyIndex, noteToHighlight, allNotes) {
			var color = Analyze.highlightNote(this.highlights.mode, this.keySignature, allNotes, noteToHighlight);
			var keyStyleOpts = {
				shadowColor: color,
				shadowBlur: 15,
				fillStyle: color,
				strokeStyle: color
			};

			return function(staveNote) {
				staveNote.setKeyStyle(keyIndex, keyStyleOpts);
			};
		},
		// returns a new Vex.Flow stave note
		_makeStaveNote: function(keys, modifiers) {
			modifiers = modifiers || [];

			var stave_note = new Vex.Flow.StaveNote({
				keys: keys,
				duration: 'w',
				clef: this.clef
			});

			for(var i = 0, len = modifiers.length; i < len; i++) {
				modifiers[i](stave_note);
			}

			return stave_note;
		}
	});

	return StaveNotater;
});
<commit_msg>remove shadow on highlighted notes<commit_after>/* global define: false */
define([
	'lodash',
	'vexflow',
	'app/util/analyze',
], function(_, Vex, Analyze) {
	"use strict";

	var StaveNotater = function(config) {
		this.init(config);
	};

	_.extend(StaveNotater.prototype, {
		init: function(config) {
			this.config = config;
			this.initConfig();
		},
		initConfig: function() {
			var required = ['chord', 'keySignature', 'clef', 'highlights'];
			_.each(required, function(propName) {
				if(this.config.hasOwnProperty(propName)) {
					this[propName] = this.config[propName];
				} else {
					throw new Error("missing required config property: "+propName);
				}
			}, this);
		},
		// returns true if there are any notes
		hasStaveNotes: function() {
			return this.chord.hasNotes(this.clef);
		},
		// returns a list of Vex.Flow stave notes
		getStaveNotes: function() {
			var note_struct = this._getNoteKeysAndModifiers();
			var stave_note = this._makeStaveNote(note_struct.keys, note_struct.modifiers);
			return [stave_note];
		},
		// returns a list of key names for this stave only ["note/octave", ...]
		_getNoteKeys: function() {
			var keySignature = this.keySignature;
			var clef = this.clef;
			var pitches = this.chord.getNotePitches(this.clef);
			var spelling = keySignature.getSpelling();
			var note, pitchClass, octave;
			var note_keys = [];

			for(var i = 0, len = pitches.length; i < len; i++) {
				pitchClass = pitches[i].pitchClass;
				octave = pitches[i].octave;
				note = spelling[pitchClass];
				octave = this.calculateOctave(pitchClass, octave, note);
				note_keys.push([note, octave].join('/'));
			}

			return note_keys;
		},
		// returns an array of objects containing each key and accidental
		_getAccidentalsOf: function(noteKeys) {
			var keySignature = this.keySignature;
			var accidentals = [];
			var accidental,
				note,
				note_spelling,
				natural_note,
				natural_found_idx,
				is_doubled;

			for(var i = 0, len = noteKeys.length; i < len; i++) {
				// skip to next iteration is for the case that the
				// note has already been assigned a natural because
				// the same note name appears twice (i.e. is doubled).
				if(accidentals[i]) {
					continue;
				}

				note = noteKeys[i];
				note_spelling = note.replace(/\/\d$/, '');
				accidental = note_spelling.substr(1); // get default accidental
				natural_note = note.replace(accidental + "\/", '/');
				natural_found_idx = noteKeys.indexOf(natural_note);
				is_doubled = natural_found_idx !== -1 && i !== natural_found_idx;

				// check to see if this note is doubled - that is, the natrual version of
				// the note is also active at the same time, in which case it needs to be
				// distinguished with a natural accidental
				if(is_doubled) {
					accidentals[natural_found_idx] = 'n';
				} else {
					// otherwise check the key signature to determine the accidental
					if(keySignature.signatureContains(note_spelling)) {
						accidental = '';
					} else if(keySignature.needsNatural(note_spelling)) {
						accidental = 'n';
					}
				}

				accidentals[i] = accidental;
			}

			return accidentals;
		},
		// returns the octave for a note, taking into account
		// the current note spelling
		calculateOctave: function(pitchClass, octave, note) {
			var note_letter = note.charAt(0);
			if(pitchClass === 0 && note_letter === 'B') {
				return octave - 1;
			} else if(pitchClass === 11 && note_letter === 'C') {
				return octave + 1;
			}
			return octave;
		},
		// returns a list of keys and associated modifiers for constructing Vex.Flow stave notes
		_getNoteKeysAndModifiers: function() {
			var keys = this._getNoteKeys();
			var accidentals = this._getAccidentalsOf(keys);
			var allMidiKeys = this.chord.getNoteNumbers(); // for highlights across stave boundaries
			var midiKeys = this.chord.getNoteNumbers(this.clef);
			var modifiers = [];

			for(var i = 0, len = keys.length; i < len; i++) {
				if(accidentals[i]) {
					modifiers.push(this._makeAccidentalModifier(i, accidentals[i]));
				}
				if(this.highlights.enabled) {
					modifiers.push(this._makeHighlightModifier(i, midiKeys[i], allMidiKeys));
				}
			}

			return {keys: keys, modifiers: modifiers};
		},
		// returns a function that will add an accidental to a Vex.Flow stave note
		_makeAccidentalModifier: function(keyIndex, accidental) {
			return function(staveNote) {
				staveNote.addAccidental(keyIndex, new Vex.Flow.Accidental(accidental));
			};
		},
		_makeHighlightModifier: function(keyIndex, noteToHighlight, allNotes) {
			var color = Analyze.highlightNote(this.highlights.mode, this.keySignature, allNotes, noteToHighlight);
			var keyStyleOpts = {
				//shadowColor: color,
				//shadowBlur: 15,
				fillStyle: color,
				strokeStyle: color
			};

			return function(staveNote) {
				staveNote.setKeyStyle(keyIndex, keyStyleOpts);
			};
		},
		// returns a new Vex.Flow stave note
		_makeStaveNote: function(keys, modifiers) {
			modifiers = modifiers || [];

			var stave_note = new Vex.Flow.StaveNote({
				keys: keys,
				duration: 'w',
				clef: this.clef
			});

			for(var i = 0, len = modifiers.length; i < len; i++) {
				modifiers[i](stave_note);
			}

			return stave_note;
		}
	});

	return StaveNotater;
});
<|endoftext|>


<commit_before>/*globals angular */

(function () {
    angular.module('channelState', ['channels', 'messages', 'users', 'socket', 'utils'])
    .factory('channelState', ['$http', '$rootScope', '$q', 'Socket', 'User', 'Channel', 'Message', 'utils', function ($http, $rootScope, $q, Socket, User, Channel, Message, utils) {
        var channel_cache = {};
        var channels_queried = false;
        var channel_min_id;

        var query_messages = function (channel) {
            // TODO: enable this to backfill
            var params = {
                count: $rootScope.message_fetch_size,
                include_deleted: 0,
                include_annotations: 1
            };

            return $http({
                method: 'GET',
                url: '/adn-proxy/stream/0/channels/' + channel.id + '/messages',
                params: params
            }).then(function (response) {
                if (response.data.meta.marker) {
                    channel.marker = response.data.meta.marker;
                }

                var messages = [];

                angular.forEach(response.data.data, function (d) {
                    messages.unshift(new Message(d));
                });

                channel.messages = messages;
            });
        };

        var on_channel = function (data, fetch) {
            var channel;
            // don't add muted channels to the channel cache
            if (data.you_muted) {
                channel = new Channel(data);
            } else {
                channel = channel_cache[data.id];

                if (channel) {
                    channel.update(data);
                } else {
                    channel = channel_cache[data.id] = new Channel(data);
                    $rootScope.channel_list = _.values(channel_cache);
                }
            }

            if (fetch) {
                get_channel(data.id, false);
            }

            return channel;
        };

        var channel_unsubscribe = function (channel_id) {
            delete channel_cache[channel_id];
            $rootScope.channel_list = _.values(channel_cache);
        };

        var mute_channel = function (channel_id) {
            return $http({
                method: 'POST',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/mute'
            }).then(function () {
                channel_unsubscribe(channel_id);
                // clear it from the channel cache, if it was there
                delete channel_cache[channel_id];
                $rootScope.channel_list = _.values(channel_cache);
            });
        };

        var unmute_channel = function (channel_id) {
            var d1 = $http({
                method: 'DELETE',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/mute'
            });
            var d2 = $http({
                method: 'POST',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/subscribe'
            });

            return $q.all(d1, d2);
        };

        var get_channel = function (channel_id, fetch_messages) {
            var promise;

            if (channel_cache[channel_id]) {
                var channel = channel_cache[channel_id];

                if (channel.messages && channel.messages.length) {
                    fetch_messages = false;
                }

                var defer = $q.defer();
                defer.resolve(channel);
                promise = defer.promise;
            } else {
                promise = $http.get('/adn-proxy/stream/0/channels/' + channel_id).then(function (response) {
                    return on_channel(response.data.data);
                });
            }

            if (fetch_messages) {
                return promise.then(function (channel) {
                    return query_messages(channel).then(function () {
                        return channel;
                    });
                });
            } else {
                return promise;
            }
        };

        var query_channels = function (num_to_fetch, fetch_older) {
            num_to_fetch = num_to_fetch || 0;
            if (channels_queried && !fetch_older) {
                var defer = $q.defer();
                defer.resolve($rootScope.channel_list);
                return defer.promise;
            }

            var params = {
                count: num_to_fetch,
                include_recent_message: 1,
                channel_types: 'net.app.core.pm'
            };

            if (channel_min_id) {
                params.before_id = channel_min_id;
            }

            var url = '/adn-proxy/stream/0/channels';
            return $http({
                method: 'GET',
                url: url,
                params: params
            }).then(function (response) {
                channel_min_id = response.data.meta.min_id;
                var fetched_channels = [];

                angular.forEach(response.data.data, function (value) {
                    var channel = new Channel(value, true);
                    channel_cache[channel.id] = channel;
                    fetched_channels.push(channel);
                });

                User.fetch_pending();

                channels_queried = true;

                $rootScope.channel_list = _.values(channel_cache);

                return fetched_channels;
            });
        };

        var fetch_muted_channels = function () {
            url = '/adn-proxy/stream/0/users/me/channels/muted';

            var params = {
                count: 200,
                include_recent_message: 1,
                channel_types: 'net.app.core.pm'
            };
            return $http({
                method: 'GET',
                url: url,
                params: params
            }).then(function (response) {
                var fetched_channels = [];
                angular.forEach(response.data.data, function (value) {
                    var channel = new Channel(value, true);
                    fetched_channels.push(channel);
                });

                $rootScope.muted_channel_list = _.values(fetched_channels);

                return fetched_channels;
            });
        }

        var update_marker = function (channel, message) {
            // don't push the marker backwards
            var message_id = utils.comparable_id(message);
            var channel_marker_id = channel.marker && utils.comparable_id(channel.marker);
            var should_update = channel_marker_id &&  message_id > channel_marker_id ||
                !channel_marker_id && message_id;
            if (should_update) {
                $http({
                    method: 'POST',
                    url: '/adn-proxy/stream/0/posts/marker',
                    data: {
                        'name': channel.marker.name,
                        'id': message.id
                    }
                }).then(function (response) {
                    channel.marker = response.data.data;
                });
            }
        };

        var display_notification = function (msg) {
            if ($rootScope.user_id !== msg.user.id && window.webkitNotifications) {
                var permission = window.webkitNotifications.checkPermission();
                if (permission === 0) {
                    // notifications are enabled
                    var n = window.webkitNotifications.createNotification(msg.user.avatar_image.url, msg.user.username, msg.text);
                    n.ondisplay = function () {
                        setTimeout(function () {
                            n.cancel();
                        }, 5000);
                    };
                    n.onclick = function () {
                        window.focus();
                        n.cancel();
                    };
                    $(window).unload(function () {
                        n.cancel();
                    });
                    n.show();
                }
            }
        };

        $rootScope.$on('stream_push', function (event, obj) {
            var channel;
            if (obj.meta.type === 'channel') {
                on_channel(obj.data);
            }

            if (obj.meta.type === 'channel_subscription') {
                if (!obj.meta.is_deleted) {
                    on_channel(obj.data.channel);
                } else {
                    channel_unsubscribe(obj.data.channel.id);
                }
            }

            if (obj.meta.type === 'message') {
                channel = channel_cache[obj.data.channel_id];
                if (channel) {
                    if (obj.meta.is_deleted) {
                        channel.messages = _.reject(channel.messages, function (m) {
                            return m.id === obj.data.id;
                        });
                    } else {
                        var msg = new Message(obj.data);
                        if (!channel.recent_message || utils.comparable_id(channel.recent_message) < utils.comparable_id(msg)) {
                            channel.recent_message = msg;
                        }

                        if (channel.marker) {
                            channel.has_unread = utils.comparable_id(channel.recent_message) > utils.comparable_id(channel.marker);
                        } else {
                            channel.has_unread = true;
                        }

                        if (!channel.messages || utils.comparable_id(_.last(channel.messages)) < utils.comparable_id(msg)) {
                            if (channel.messages && channel.messages.length) {
                                channel.messages.push(msg);
                            }
                            display_notification(msg);
                        }
                    }
                }
            }

            // only update our own markers
            if (obj.meta.type === 'stream_marker' && obj.meta.user_id === $rootScope.user_id) {
                channel = channel_cache[obj.meta.channel_id];

                if (channel) {
                    channel.marker = obj.data.marker;

                    if (channel.recent_message) {
                        channel.has_unread = utils.comparable_id(channel.recent_message) > utils.comparable_id(channel.marker);
                    } else {
                        channel.has_unread = false;
                    }
                }
            }
        });

        return {
            'get_channel': get_channel,
            'query_channels': query_channels,
            'fetch_muted_channels': fetch_muted_channels,
            'update_marker': update_marker,
            'mute_channel': mute_channel,
            'unmute_channel': unmute_channel
        };
    }]);
})();
<commit_msg>fix sending msgs into empty channel again<commit_after>/*globals angular */

(function () {
    angular.module('channelState', ['channels', 'messages', 'users', 'socket', 'utils'])
    .factory('channelState', ['$http', '$rootScope', '$q', '$routeParams', 'Socket', 'User', 'Channel', 'Message', 'utils', function ($http, $rootScope, $q, $routeParams, Socket, User, Channel, Message, utils) {
        var channel_cache = {};
        var channels_queried = false;
        var channel_min_id;

        var query_messages = function (channel) {
            // TODO: enable this to backfill
            var params = {
                count: $rootScope.message_fetch_size,
                include_deleted: 0,
                include_annotations: 1
            };

            return $http({
                method: 'GET',
                url: '/adn-proxy/stream/0/channels/' + channel.id + '/messages',
                params: params
            }).then(function (response) {
                if (response.data.meta.marker) {
                    channel.marker = response.data.meta.marker;
                }

                var messages = [];

                angular.forEach(response.data.data, function (d) {
                    messages.unshift(new Message(d));
                });

                channel.messages = messages;
            });
        };

        var on_channel = function (data, fetch) {
            var channel;
            // don't add muted channels to the channel cache
            if (data.you_muted) {
                channel = new Channel(data);
            } else {
                channel = channel_cache[data.id];

                if (channel) {
                    channel.update(data);
                } else {
                    channel = channel_cache[data.id] = new Channel(data);
                    $rootScope.channel_list = _.values(channel_cache);
                }
            }

            if (fetch) {
                get_channel(data.id, false);
            }

            return channel;
        };

        var channel_unsubscribe = function (channel_id) {
            delete channel_cache[channel_id];
            $rootScope.channel_list = _.values(channel_cache);
        };

        var mute_channel = function (channel_id) {
            return $http({
                method: 'POST',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/mute'
            }).then(function () {
                channel_unsubscribe(channel_id);
                // clear it from the channel cache, if it was there
                delete channel_cache[channel_id];
                $rootScope.channel_list = _.values(channel_cache);
            });
        };

        var unmute_channel = function (channel_id) {
            var d1 = $http({
                method: 'DELETE',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/mute'
            });
            var d2 = $http({
                method: 'POST',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/subscribe'
            });

            return $q.all(d1, d2);
        };

        var get_channel = function (channel_id, fetch_messages) {
            var promise;

            if (channel_cache[channel_id]) {
                var channel = channel_cache[channel_id];

                if (channel.messages && channel.messages.length) {
                    fetch_messages = false;
                }

                var defer = $q.defer();
                defer.resolve(channel);
                promise = defer.promise;
            } else {
                promise = $http.get('/adn-proxy/stream/0/channels/' + channel_id).then(function (response) {
                    return on_channel(response.data.data);
                });
            }

            if (fetch_messages) {
                return promise.then(function (channel) {
                    return query_messages(channel).then(function () {
                        return channel;
                    });
                });
            } else {
                return promise;
            }
        };

        var query_channels = function (num_to_fetch, fetch_older) {
            num_to_fetch = num_to_fetch || 0;
            if (channels_queried && !fetch_older) {
                var defer = $q.defer();
                defer.resolve($rootScope.channel_list);
                return defer.promise;
            }

            var params = {
                count: num_to_fetch,
                include_recent_message: 1,
                channel_types: 'net.app.core.pm'
            };

            if (channel_min_id) {
                params.before_id = channel_min_id;
            }

            var url = '/adn-proxy/stream/0/channels';
            return $http({
                method: 'GET',
                url: url,
                params: params
            }).then(function (response) {
                channel_min_id = response.data.meta.min_id;
                var fetched_channels = [];

                angular.forEach(response.data.data, function (value) {
                    var channel = new Channel(value, true);
                    channel_cache[channel.id] = channel;
                    fetched_channels.push(channel);
                });

                User.fetch_pending();

                channels_queried = true;

                $rootScope.channel_list = _.values(channel_cache);

                return fetched_channels;
            });
        };

        var fetch_muted_channels = function () {
            url = '/adn-proxy/stream/0/users/me/channels/muted';

            var params = {
                count: 200,
                include_recent_message: 1,
                channel_types: 'net.app.core.pm'
            };
            return $http({
                method: 'GET',
                url: url,
                params: params
            }).then(function (response) {
                var fetched_channels = [];
                angular.forEach(response.data.data, function (value) {
                    var channel = new Channel(value, true);
                    fetched_channels.push(channel);
                });

                $rootScope.muted_channel_list = _.values(fetched_channels);

                return fetched_channels;
            });
        }

        var update_marker = function (channel, message) {
            // don't push the marker backwards
            var message_id = utils.comparable_id(message);
            var channel_marker_id = channel.marker && utils.comparable_id(channel.marker);
            var should_update = channel_marker_id &&  message_id > channel_marker_id ||
                !channel_marker_id && message_id;
            if (should_update) {
                $http({
                    method: 'POST',
                    url: '/adn-proxy/stream/0/posts/marker',
                    data: {
                        'name': channel.marker.name,
                        'id': message.id
                    }
                }).then(function (response) {
                    channel.marker = response.data.data;
                });
            }
        };

        var display_notification = function (msg) {
            if ($rootScope.user_id !== msg.user.id && window.webkitNotifications) {
                var permission = window.webkitNotifications.checkPermission();
                if (permission === 0) {
                    // notifications are enabled
                    var n = window.webkitNotifications.createNotification(msg.user.avatar_image.url, msg.user.username, msg.text);
                    n.ondisplay = function () {
                        setTimeout(function () {
                            n.cancel();
                        }, 5000);
                    };
                    n.onclick = function () {
                        window.focus();
                        n.cancel();
                    };
                    $(window).unload(function () {
                        n.cancel();
                    });
                    n.show();
                }
            }
        };

        $rootScope.$on('stream_push', function (event, obj) {
            var channel;
            if (obj.meta.type === 'channel') {
                on_channel(obj.data);
            }

            if (obj.meta.type === 'channel_subscription') {
                if (!obj.meta.is_deleted) {
                    on_channel(obj.data.channel);
                } else {
                    channel_unsubscribe(obj.data.channel.id);
                }
            }

            if (obj.meta.type === 'message') {
                channel = channel_cache[obj.data.channel_id];
                if (channel) {
                    if (obj.meta.is_deleted) {
                        channel.messages = _.reject(channel.messages, function (m) {
                            return m.id === obj.data.id;
                        });
                    } else {
                        var msg = new Message(obj.data);
                        if (!channel.recent_message || utils.comparable_id(channel.recent_message) < utils.comparable_id(msg)) {
                            channel.recent_message = msg;
                        }

                        if (channel.marker) {
                            channel.has_unread = utils.comparable_id(channel.recent_message) > utils.comparable_id(channel.marker);
                        } else {
                            channel.has_unread = true;
                        }

                        if (!channel.messages || utils.comparable_id(_.last(channel.messages)) < utils.comparable_id(msg)) {
                            if (channel.messages) {
                                // this is a hack so that you can still send messages into an empty channel (eg all messages deleted)
                                // need to fix this, channel.messages.length shouldn't be used to tell whether you're in a channel or in the main window
                                if (channel.messages.length || $routeParams.channel_id) {
                                    channel.messages.push(msg);
                                }
                            }
                            display_notification(msg);
                        }
                    }
                }
            }

            // only update our own markers
            if (obj.meta.type === 'stream_marker' && obj.meta.user_id === $rootScope.user_id) {
                channel = channel_cache[obj.meta.channel_id];

                if (channel) {
                    channel.marker = obj.data.marker;

                    if (channel.recent_message) {
                        channel.has_unread = utils.comparable_id(channel.recent_message) > utils.comparable_id(channel.marker);
                    } else {
                        channel.has_unread = false;
                    }
                }
            }
        });

        return {
            'get_channel': get_channel,
            'query_channels': query_channels,
            'fetch_muted_channels': fetch_muted_channels,
            'update_marker': update_marker,
            'mute_channel': mute_channel,
            'unmute_channel': unmute_channel
        };
    }]);
})();
<|endoftext|>


<commit_before>
var levelgraph = require("../");
var levelup = require("levelup");
var tmp = require("tmp");

describe("navigator", function() {

  var db;

  beforeEach(function(done) {
    tmp.dir(function(err, dir) {
      if (err) {
        done(err);
        return;
      }

      db = levelgraph(levelup(dir));
      db.put(require("./fixture/foaf"), done);
    });
  });

  afterEach(function(done) {
    db.close(done);
  });

  it("should navigate to a single vertex", function(done) {
    db.nav("matteo").values(function(err, results) {
      expect(results).to.eql(["matteo"]);
      done();
    });
  });

  it("should follow an arch going out a vertex", function(done) {
    db.nav("matteo").archOut("friend").values(function(err, friends) {
      expect(friends).to.eql(["daniele"]);
      done();
    });
  });

  it("should follow an arch going in a vertex", function(done) {
    db.nav("davide").archIn("friend").values(function(err, friends) {
      expect(friends).to.eql(["marco"]);
      done();
    });
  });

  it("should follow multiple archs, in and out a path",
     function(done) {
    db.nav("davide").archIn("friend").archIn("friend").archOut("friend").
      values(function(err, friends) {

      expect(friends).to.eql(["marco", "matteo"]);
      done();
    });
  });

  it("should follow multiple archs, in and out a path using a stream",
     function(done) {
    var stream = db.nav("davide").archIn("friend").archIn("friend").archOut("friend").valuesStream();

    stream.on("data", function(data) {
      expect(["marco", "matteo"].indexOf(data) >= 0).to.be.ok;
    });

    stream.on("end", done);
  });

  it("should allow to set the name of the variables",
     function(done) {
    db.nav("marco").archIn("friend").as("a").archOut("friend").archOut("friend").as("a").
      values(function(err, friends) {

      expect(friends).to.eql(["daniele"]);
      done();
    });
  });

  it("should allow to bind a variable",
     function(done) {
    db.nav("matteo").archIn("friend").bind("lucio").archOut("friend").bind("marco").
      values(function(err, friends) {

      expect(friends).to.eql(["marco"]);
      done();
    });
  });

  it("should allow to start the navigation from a variable",
     function(done) {
    db.nav().archOut("friend").bind("matteo").archOut("friend").
      values(function(err, friends) {

      expect(friends).to.eql(["daniele"]);
      done();
    });
  });

  it("should return the contexts",
     function(done) {
    db.nav("daniele").archOut("friend").as("a").
      contexts(function(err, contexts) {

      expect(contexts).to.eql([{ a: "marco" }, { a: "matteo" }]);
      done();
    });
  });

  it("should return the context as a stream",
     function(done) {

    var contexts = [{ a: "marco" }, { a: "matteo" }];

    var stream = db.nav("daniele").archOut("friend").as("a").
      contextsStream();

    stream.on("data", function(data) {
      expect(data).to.eql(contexts.shift());
    });

    stream.on("end", done);
  });
});
<commit_msg>Testing the behavior of Navigator.contexts with no conditions.<commit_after>
var levelgraph = require("../");
var levelup = require("levelup");
var tmp = require("tmp");

describe("navigator", function() {

  var db;

  beforeEach(function(done) {
    tmp.dir(function(err, dir) {
      if (err) {
        done(err);
        return;
      }

      db = levelgraph(levelup(dir));
      db.put(require("./fixture/foaf"), done);
    });
  });

  afterEach(function(done) {
    db.close(done);
  });

  it("should navigate to a single vertex", function(done) {
    db.nav("matteo").values(function(err, results) {
      expect(results).to.eql(["matteo"]);
      done();
    });
  });

  it("should follow an arch going out a vertex", function(done) {
    db.nav("matteo").archOut("friend").values(function(err, friends) {
      expect(friends).to.eql(["daniele"]);
      done();
    });
  });

  it("should follow an arch going in a vertex", function(done) {
    db.nav("davide").archIn("friend").values(function(err, friends) {
      expect(friends).to.eql(["marco"]);
      done();
    });
  });

  it("should follow multiple archs, in and out a path",
     function(done) {
    db.nav("davide").archIn("friend").archIn("friend").archOut("friend").
      values(function(err, friends) {

      expect(friends).to.eql(["marco", "matteo"]);
      done();
    });
  });

  it("should follow multiple archs, in and out a path using a stream",
     function(done) {
    var stream = db.nav("davide").archIn("friend").archIn("friend").archOut("friend").valuesStream();

    stream.on("data", function(data) {
      expect(["marco", "matteo"].indexOf(data) >= 0).to.be.ok;
    });

    stream.on("end", done);
  });

  it("should allow to set the name of the variables",
     function(done) {
    db.nav("marco").archIn("friend").as("a").archOut("friend").archOut("friend").as("a").
      values(function(err, friends) {

      expect(friends).to.eql(["daniele"]);
      done();
    });
  });

  it("should allow to bind a variable",
     function(done) {
    db.nav("matteo").archIn("friend").bind("lucio").archOut("friend").bind("marco").
      values(function(err, friends) {

      expect(friends).to.eql(["marco"]);
      done();
    });
  });

  it("should allow to start the navigation from a variable",
     function(done) {
    db.nav().archOut("friend").bind("matteo").archOut("friend").
      values(function(err, friends) {

      expect(friends).to.eql(["daniele"]);
      done();
    });
  });

  it("should return the contexts",
     function(done) {
    db.nav("daniele").archOut("friend").as("a").
      contexts(function(err, contexts) {

      expect(contexts).to.eql([{ a: "marco" }, { a: "matteo" }]);
      done();
    });
  });

  it("should return the context as a stream",
     function(done) {

    var contexts = [{ a: "marco" }, { a: "matteo" }];

    var stream = db.nav("daniele").archOut("friend").as("a").
      contextsStream();

    stream.on("data", function(data) {
      expect(data).to.eql(contexts.shift());
    });

    stream.on("end", done);
  });

  it("should return an empty context if no condition is specified",
     function(done) {
    db.nav("daniele").contexts(function(err, contexts) {
      expect(contexts).to.eql([{}]);
      done();
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

import $ from 'jquery';
import React from 'react';
import moment from 'moment';
import { Modal, Button } from 'react-bootstrap';

import SetGame from './setgame';
import SetCard from './setcard';

export default class Solitaire extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      cards: [],
      selected: new Set(),      // Set<String>
      found: new Set(),         // Set<Set<String>>
      solved: false,
      starttime: null,
    };
  }

  componentWillMount() {
    let onSuccess = function(response) {
      this.setState({
        cards: response.cards,
      });
    }.bind(this);
    let onError = function(response) {
      this.setState({
        error: response
      });
    }.bind(this);
    $.get(this.props.url).then(onSuccess, onError);
  }

  /**
   * @param {Event} evt - the event
   * @param {Object} card - the card we clicked
   */
  onClickSetCard(evt, card) {
    let newState = {};
    if (!this.state.starttime) {
      Object.assign(newState, {starttime: moment()});
    }

    let cardString = SetCard.stringify(card);
    if (this.state.selected.has(cardString)) {
      let selectedCopy = new Set(this.state.selected);
      selectedCopy.delete(cardString);
      Object.assign(newState, {selected: selectedCopy});
    }
    else {
      Object.assign(newState, this.setState({
        selected: this.state.selected.add(cardString)
      }));
    }

    if (this.state.selected.size == 3) {
      let data = {
        cards: [...this.state.selected].map(SetCard.objectify)
      };
      let xhr = new XMLHttpRequest();

      xhr.open('PUT', this.props.url);
      xhr.setRequestHeader('Content-Type', 'application/json');
      xhr.onload = () => {
        if (xhr.status == 200) {
          let response = JSON.parse(xhr.responseText);
          switch(response['result']) {
            case 'OK':
              let r = this.state.selected;
              this.setState({
                found: this.state.found.add(new Set(r)),
                solved: response['solved'],
                selected: new Set(),
              });
              break;
            case 'NOT_A_SET':
              break;
            case 'ALREADY_FOUND':
              this.setState({
                selected: new Set(),
              });
              break;
            default:
              throw('This should never happen.');
          }
        }
      };
      xhr.send(JSON.stringify(data));
    }

    this.setState(newState);
  }

  onClickNewGame() {
    $.ajax(this.props.url, {
      data: { reset: true },
      method: 'GET'
    }).then((response) => {
      this.setState({
        cards: response.cards,
        selected: new Set(),
        found: new Set(),
        solved: false,
        starttime: null
      });
    }, (response) => {
      console.error(response);
    });
  }

  /**
   * @param {the_set} Set<String> - the cards in this set
   * @param {index} Number - the index of this set in the list of sets
   */
  renderSet(the_set, index) {
    return (
      <ul className="this-set" key={`found${index}`}>
        {[...the_set].map((card_string) => {
          return (

              <SetCard {...SetCard.objectify(card_string)} />

          );
        })}

    );
  }

  renderSetsFound() {
    return (

Found so far:

        {
          [...this.state.found].map(this.renderSet)
        }

    );
  }

  render() {
    return (

        <Modal show={this.state.solved}>
          <Modal.Body>

Solved! In { moment().diff(this.state.starttime, 'seconds') } seconds

          </Modal.Body>
          <Modal.Footer>
            <Button bsSize="large" bsStyle="success" onClick={this.onClickNewGame.bind(this)}>New Game...</Button>
          </Modal.Footer>
        </Modal>
        <SetGame
          onClickSetCard={this.onClickSetCard.bind(this)}
          {... _.pick(this.state, 'cards', 'selected')}
        />
        {this.renderSetsFound()}

    );
  }
}
<commit_msg>fix jsdoc<commit_after>'use strict';

import $ from 'jquery';
import React from 'react';
import moment from 'moment';
import { Modal, Button } from 'react-bootstrap';

import SetGame from './setgame';
import SetCard from './setcard';

export default class Solitaire extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      cards: [],
      selected: new Set(),      // Set<String>
      found: new Set(),         // Set<Set<String>>
      solved: false,
      starttime: null,
    };
  }

  componentWillMount() {
    let onSuccess = function(response) {
      this.setState({
        cards: response.cards,
      });
    }.bind(this);
    let onError = function(response) {
      this.setState({
        error: response
      });
    }.bind(this);
    $.get(this.props.url).then(onSuccess, onError);
  }

  /**
   * @param {Event} evt - the event
   * @param {Object} card - the card we clicked
   */
  onClickSetCard(evt, card) {
    let newState = {};
    if (!this.state.starttime) {
      Object.assign(newState, {starttime: moment()});
    }

    let cardString = SetCard.stringify(card);
    if (this.state.selected.has(cardString)) {
      let selectedCopy = new Set(this.state.selected);
      selectedCopy.delete(cardString);
      Object.assign(newState, {selected: selectedCopy});
    }
    else {
      Object.assign(newState, this.setState({
        selected: this.state.selected.add(cardString)
      }));
    }

    if (this.state.selected.size == 3) {
      let data = {
        cards: [...this.state.selected].map(SetCard.objectify)
      };
      let xhr = new XMLHttpRequest();

      xhr.open('PUT', this.props.url);
      xhr.setRequestHeader('Content-Type', 'application/json');
      xhr.onload = () => {
        if (xhr.status == 200) {
          let response = JSON.parse(xhr.responseText);
          switch(response['result']) {
            case 'OK':
              let r = this.state.selected;
              this.setState({
                found: this.state.found.add(new Set(r)),
                solved: response['solved'],
                selected: new Set(),
              });
              break;
            case 'NOT_A_SET':
              break;
            case 'ALREADY_FOUND':
              this.setState({
                selected: new Set(),
              });
              break;
            default:
              throw('This should never happen.');
          }
        }
      };
      xhr.send(JSON.stringify(data));
    }

    this.setState(newState);
  }

  onClickNewGame() {
    $.ajax(this.props.url, {
      data: { reset: true },
      method: 'GET'
    }).then((response) => {
      this.setState({
        cards: response.cards,
        selected: new Set(),
        found: new Set(),
        solved: false,
        starttime: null
      });
    }, (response) => {
      console.error(response);
    });
  }

  /**
   * @param {Set<String>} the_set - the cards in this set
   * @param {Number} index - the index of this set in the list of sets
   */
  renderSet(the_set, index) {
    return (
      <ul className="this-set" key={`found${index}`}>
        {[...the_set].map((card_string) => {
          return (

              <SetCard {...SetCard.objectify(card_string)} />

          );
        })}

    );
  }

  renderSetsFound() {
    return (

Found so far:

        {
          [...this.state.found].map(this.renderSet)
        }

    );
  }

  render() {
    return (

        <Modal show={this.state.solved}>
          <Modal.Body>

Solved! In { moment().diff(this.state.starttime, 'seconds') } seconds

          </Modal.Body>
          <Modal.Footer>
            <Button bsSize="large" bsStyle="success" onClick={this.onClickNewGame.bind(this)}>New Game...</Button>
          </Modal.Footer>
        </Modal>
        <SetGame
          onClickSetCard={this.onClickSetCard.bind(this)}
          {... _.pick(this.state, 'cards', 'selected')}
        />
        {this.renderSetsFound()}

    );
  }
}
<|endoftext|>


<commit_before>/**
 * @file SPMetadata.js
 * @author Tony Ngan
 * @desc  Metadata of service provider
 */
var namespace = require('./urn').namespace;
var Metadata = require('./Metadata');
var xml = require('xml');
var SamlLib = require('./SamlLib');
/**
 * @param  {object/string} meta (either file path in string format or configuation in object)
 * @return {object} prototypes including public functions
 */
module.exports = function(meta) {
    var byMetadata = typeof meta === 'string';

    if(!byMetadata) {
        var entityID = meta.entityID,
            authnRequestsSigned = meta.authnRequestsSigned === true,
            wantAssertionsSigned = meta.wantAssertionsSigned === true,
            signingCertFile = meta.signingCertFile,
            encryptCertFile = meta.encryptCertFile,
            nameIDFormat = meta.nameIDFormat || [],
            singleLogoutService = meta.singleLogoutService || [];
            assertionConsumerService = meta.assertionConsumerService || [];

        var SPSSODescriptor = [{
            _attr: {
                AuthnRequestsSigned: authnRequestsSigned.toString(),
                WantAssertionsSigned: wantAssertionsSigned.toString(),
                protocolSupportEnumeration: namespace.names.protocol
            }
        }];

        if(signingCertFile) {
            SPSSODescriptor.push(SamlLib.createKeySection('signing', signingCertFile));
        } else {
            console.warn('Construct service provider - missing signing certificate');
        }

        if(encryptCertFile) {
            SPSSODescriptor.push(SamlLib.createKeySection('encrypt', encryptCertFile));
        } else {
            console.warn('Construct service provider - missing encrypt certificate');
        }

        if(nameIDFormat && nameIDFormat.length > 0) {
            nameIDFormat.forEach(function(f) {
                SPSSODescriptor.push({
                    NameIDFormat: f
                });
            });
        }

        if(singleLogoutService && singleLogoutService.length > 0) {
            singleLogoutService.forEach(function(a) {
                var _attr = {};
                var _indexCount = 0;

                if(a.isDefault) {
                    _attr.isDefault = true;
                }
                _attr.index = (_indexCount++).toString();
                _attr.Binding = a.Binding;
                _attr.Location = a.Location;
                SPSSODescriptor.push({
                    SingleLogoutService: [{
                        _attr: _attr
                    }]
                });
            });
        }

        if(assertionConsumerService && assertionConsumerService.length > 0) {
            assertionConsumerService.forEach(function(a) {
                var _attr = {};
                var _indexCount = 0;
                if(a.isDefault) {
                    _attr.isDefault = true;
                }
                _attr.index = (_indexCount++).toString();
                _attr.Binding = a.Binding;
                _attr.Location = a.Location;
                SPSSODescriptor.push({
                    AssertionConsumerService: [{
                        _attr: _attr
                    }]
                });
            });
        } else {
            throw new Error('Missing endpoint of AssertionConsumerService');
        }

        // Create a new metadata by setting
        meta = xml([{
            EntityDescriptor: [{
                _attr: {
                    'xmlns:md': namespace.names.metadata,
                    'xmlns:assertion': namespace.names.assertion,
                    'xmlns:ds':'http://www.w3.org/2000/09/xmldsig#',
                    entityID: entityID
                }
            },{
                SPSSODescriptor: SPSSODescriptor
            }]
        }]);
    }
    /**
     * @desc SP Metadata is for creating Service Provider, provides a set of API to manage the actions in SP.
     */
    function SPMetadata() {}
    /**
     * @desc  Initialize with creating a new metadata object
     * @param {string/objects} meta     declares path of the metadata
     * @param {array of Objects}        high-level XML element selector
     */
    SPMetadata.prototype = new Metadata(meta, [{
        localName: 'SPSSODescriptor',
        attributes: ['WantAssertionsSigned', 'AuthnRequestsSigned']
    },{
        localName: 'AssertionConsumerService',
        attributes: ['Binding', 'Location', 'isDefault', 'index']
    }], !byMetadata);
    /**
     * @desc Get the preference whether it wants a signed assertion response
     * @return {boolean} Wantassertionssigned
     */
    SPMetadata.prototype.isWantAssertionsSigned = function isWantAssertionsSigned() {
        return this.meta.spssodescriptor.wantassertionssigned === 'true';
    };
    /**
     * @desc Get the preference whether it signs request
     * @return {boolean} Authnrequestssigned
     */
    SPMetadata.prototype.isAuthnRequestSigned = function isAuthnRequestSigned() {
        return this.meta.spssodescriptor.authnrequestssigned === 'true';
    };
    /**
     * @desc Get the entity endpoint for assertion consumer service
     * @param  {string} binding         protocol binding (e.g. redirect, post)
     * @return {string/[string]} URL of endpoint(s)
     */
    SPMetadata.prototype.getAssertionConsumerService = function getAssertionConsumerService(binding) {
        if(typeof binding === 'string') {
            var _location;
            var _binding = namespace.binding[binding];

            if(this.meta.assertionconsumerservice.length > 0) {
                this.meta.assertionconsumerservice.forEach(function(obj) {
                    if(obj.binding === _binding) {
                        _location = obj.location;
                        return;
                    }
                });
            } else {
                if(this.meta.assertionconsumerservice.binding === _binding) {
                    _location = this.meta.assertionconsumerservice.location;
                    return;
                }
            }
            return _location;
        } else {
            return this.meta.singlelogoutservice;
        }
    };
    /**
     * @desc return the prototype
     */
    return SPMetadata.prototype;
};
<commit_msg>Fix SPMetadata.getAssertionConsumerService<commit_after>/**
 * @file SPMetadata.js
 * @author Tony Ngan
 * @desc  Metadata of service provider
 */
var namespace = require('./urn').namespace;
var Metadata = require('./Metadata');
var xml = require('xml');
var SamlLib = require('./SamlLib');
/**
 * @param  {object/string} meta (either file path in string format or configuation in object)
 * @return {object} prototypes including public functions
 */
module.exports = function(meta) {
    var byMetadata = typeof meta === 'string';

    if(!byMetadata) {
        var entityID = meta.entityID,
            authnRequestsSigned = meta.authnRequestsSigned === true,
            wantAssertionsSigned = meta.wantAssertionsSigned === true,
            signingCertFile = meta.signingCertFile,
            encryptCertFile = meta.encryptCertFile,
            nameIDFormat = meta.nameIDFormat || [],
            singleLogoutService = meta.singleLogoutService || [];
            assertionConsumerService = meta.assertionConsumerService || [];

        var SPSSODescriptor = [{
            _attr: {
                AuthnRequestsSigned: authnRequestsSigned.toString(),
                WantAssertionsSigned: wantAssertionsSigned.toString(),
                protocolSupportEnumeration: namespace.names.protocol
            }
        }];

        if(signingCertFile) {
            SPSSODescriptor.push(SamlLib.createKeySection('signing', signingCertFile));
        } else {
            console.warn('Construct service provider - missing signing certificate');
        }

        if(encryptCertFile) {
            SPSSODescriptor.push(SamlLib.createKeySection('encrypt', encryptCertFile));
        } else {
            console.warn('Construct service provider - missing encrypt certificate');
        }

        if(nameIDFormat && nameIDFormat.length > 0) {
            nameIDFormat.forEach(function(f) {
                SPSSODescriptor.push({
                    NameIDFormat: f
                });
            });
        }

        if(singleLogoutService && singleLogoutService.length > 0) {
            singleLogoutService.forEach(function(a) {
                var _attr = {};
                var _indexCount = 0;

                if(a.isDefault) {
                    _attr.isDefault = true;
                }
                _attr.index = (_indexCount++).toString();
                _attr.Binding = a.Binding;
                _attr.Location = a.Location;
                SPSSODescriptor.push({
                    SingleLogoutService: [{
                        _attr: _attr
                    }]
                });
            });
        }

        if(assertionConsumerService && assertionConsumerService.length > 0) {
            assertionConsumerService.forEach(function(a) {
                var _attr = {};
                var _indexCount = 0;
                if(a.isDefault) {
                    _attr.isDefault = true;
                }
                _attr.index = (_indexCount++).toString();
                _attr.Binding = a.Binding;
                _attr.Location = a.Location;
                SPSSODescriptor.push({
                    AssertionConsumerService: [{
                        _attr: _attr
                    }]
                });
            });
        } else {
            throw new Error('Missing endpoint of AssertionConsumerService');
        }

        // Create a new metadata by setting
        meta = xml([{
            EntityDescriptor: [{
                _attr: {
                    'xmlns:md': namespace.names.metadata,
                    'xmlns:assertion': namespace.names.assertion,
                    'xmlns:ds':'http://www.w3.org/2000/09/xmldsig#',
                    entityID: entityID
                }
            },{
                SPSSODescriptor: SPSSODescriptor
            }]
        }]);
    }
    /**
     * @desc SP Metadata is for creating Service Provider, provides a set of API to manage the actions in SP.
     */
    function SPMetadata() {}
    /**
     * @desc  Initialize with creating a new metadata object
     * @param {string/objects} meta     declares path of the metadata
     * @param {array of Objects}        high-level XML element selector
     */
    SPMetadata.prototype = new Metadata(meta, [{
        localName: 'SPSSODescriptor',
        attributes: ['WantAssertionsSigned', 'AuthnRequestsSigned']
    },{
        localName: 'AssertionConsumerService',
        attributes: ['Binding', 'Location', 'isDefault', 'index']
    }], !byMetadata);
    /**
     * @desc Get the preference whether it wants a signed assertion response
     * @return {boolean} Wantassertionssigned
     */
    SPMetadata.prototype.isWantAssertionsSigned = function isWantAssertionsSigned() {
        return this.meta.spssodescriptor.wantassertionssigned === 'true';
    };
    /**
     * @desc Get the preference whether it signs request
     * @return {boolean} Authnrequestssigned
     */
    SPMetadata.prototype.isAuthnRequestSigned = function isAuthnRequestSigned() {
        return this.meta.spssodescriptor.authnrequestssigned === 'true';
    };
    /**
     * @desc Get the entity endpoint for assertion consumer service
     * @param  {string} binding         protocol binding (e.g. redirect, post)
     * @return {string/[string]} URL of endpoint(s)
     */
    SPMetadata.prototype.getAssertionConsumerService = function getAssertionConsumerService(binding) {
        if(typeof binding === 'string') {
            var _location;
            var _binding = namespace.binding[binding];

            if(this.meta.assertionconsumerservice.length > 0) {
                this.meta.assertionconsumerservice.forEach(function(obj) {
                    if(obj.binding === _binding) {
                        _location = obj.location;
                        return;
                    }
                });
            } else {
                if(this.meta.assertionconsumerservice.binding === _binding) {
                    _location = this.meta.assertionconsumerservice.location;
                }
            }
            return _location;
        } else {
            return this.meta.singlelogoutservice;
        }
    };
    /**
     * @desc return the prototype
     */
    return SPMetadata.prototype;
};
<|endoftext|>


<commit_before>'use strict';

const { DEFAULT_INPUT_CHARSET } = require('./constants');
const { validateCharset } = require('./validate');

// Normalize charset, including adding defaults and validating
const normalizeCharset = function ({ charset, format }) {
  const charsetA = addDefaultCharset({ charset, format });

  const charsetB = charsetA.toLowerCase();

  validateCharset({ charset: charsetB, format });

  return charsetB;
};

const addDefaultCharset = function ({ charset, format: { charsets = [] } }) {
  return charset ||
    // Charset specified by this format
    charsets[0] ||
    DEFAULT_INPUT_CHARSET;
};

module.exports = {
  normalizeCharset,
};
<commit_msg>Refactoring<commit_after>'use strict';

const { DEFAULT_INPUT_CHARSET } = require('./constants');
const { validateCharset } = require('./validate');

// Normalize charset, including adding defaults and validating
const normalizeCharset = function ({ charset, format }) {
  const charsetA = addDefaultCharset({ charset, format });

  const charsetB = charsetA.toLowerCase();

  validateCharset({ charset: charsetB, format });

  return charsetB;
};

// Add default charsets, including the format's default charset
const addDefaultCharset = function ({ charset, format: { charsets = [] } }) {
  return charset || charsets[0] || DEFAULT_INPUT_CHARSET;
};

module.exports = {
  normalizeCharset,
};
<|endoftext|>


<commit_before>import Model, {attr} from '@ember-data/model';
import ValidationEngine from 'ghost-admin/mixins/validation-engine';

export default Model.extend(ValidationEngine, {
    validationType: 'offer',

    name: attr('string'),
    code: attr('string'),
    cadence: attr('string'),
    status: attr('string', {defaultValue: 'active'}),
    tier: attr(),
    stripeCouponId: attr('string'),
    redemptionCount: attr('number'),
    currency: attr('string'),
    type: attr('string', {defaultValue: 'percent'}),
    amount: attr('number'),
    duration: attr('string', {defaultValue: 'forever'}),
    durationInMonths: attr('number'),
    displayTitle: attr('string'),
    displayDescription: attr('string'),
    createdAtUTC: attr('moment-utc'),
    updatedAtUTC: attr('moment-utc')
});
<commit_msg>Updated default offer duration as once<commit_after>import Model, {attr} from '@ember-data/model';
import ValidationEngine from 'ghost-admin/mixins/validation-engine';

export default Model.extend(ValidationEngine, {
    validationType: 'offer',

    name: attr('string'),
    code: attr('string'),
    cadence: attr('string'),
    status: attr('string', {defaultValue: 'active'}),
    tier: attr(),
    stripeCouponId: attr('string'),
    redemptionCount: attr('number'),
    currency: attr('string'),
    type: attr('string', {defaultValue: 'percent'}),
    amount: attr('number'),
    duration: attr('string', {defaultValue: 'once'}),
    durationInMonths: attr('number'),
    displayTitle: attr('string'),
    displayDescription: attr('string'),
    createdAtUTC: attr('moment-utc'),
    updatedAtUTC: attr('moment-utc')
});
<|endoftext|>


<commit_before>/*globals angular */

(function () {
    angular.module('channelState', ['channels', 'messages', 'users', 'socket', 'utils'])
    .factory('channelState', ['$http', '$rootScope', '$q', 'Socket', 'User', 'Channel', 'Message', 'utils', function ($http, $rootScope, $q, Socket, User, Channel, Message, utils) {
        var channel_cache = {};
        var channels_queried = false;
        var channel_min_id;

        var query_messages = function (channel) {
            // TODO: enable this to backfill
            var params = {
                count: $rootScope.message_fetch_size,
                include_deleted: 0,
                include_annotations: 1
            };

            return $http({
                method: 'GET',
                url: '/adn-proxy/stream/0/channels/' + channel.id + '/messages',
                params: params
            }).then(function (response) {
                if (response.data.meta.marker) {
                    channel.marker = response.data.meta.marker;
                }

                var messages = [];

                angular.forEach(response.data.data, function (d) {
                    messages.unshift(new Message(d));
                });

                channel.messages = messages;
            });
        };

        var on_channel = function (data, fetch) {
            var channel;
            // don't add muted channels to the channel cache
            if (data.you_muted) {
                channel = new Channel(data);
            } else {
                channel = channel_cache[data.id];

                if (channel) {
                    channel.update(data);
                } else {
                    channel = channel_cache[data.id] = new Channel(data);
                    $rootScope.channel_list = _.values(channel_cache);
                }
            }

            if (fetch) {
                get_channel(data.id, false);
            }

            return channel;
        };

        var channel_unsubscribe = function (channel_id) {
            delete channel_cache[channel_id];
            $rootScope.channel_list = _.values(channel_cache);
        };

        var mute_channel = function (channel_id) {
            return $http({
                method: 'POST',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/mute'
            }).then(function () {
                channel_unsubscribe(channel_id);
                // clear it from the channel cache, if it was there
                delete channel_cache[channel_id];
                $rootScope.channel_list = _.values(channel_cache);
            });
        };

        var unmute_channel = function (channel_id) {
            var d1 = $http({
                method: 'DELETE',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/mute'
            });
            var d2 = $http({
                method: 'POST',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/subscribe'
            });

            return $q.all(d1, d2);
        };

        var get_channel = function (channel_id, fetch_messages) {
            var promise;

            if (channel_cache[channel_id]) {
                var channel = channel_cache[channel_id];

                if (channel.messages && channel.messages.length) {
                    fetch_messages = false;
                }

                var defer = $q.defer();
                defer.resolve(channel);
                promise = defer.promise;
            } else {
                promise = $http.get('/adn-proxy/stream/0/channels/' + channel_id).then(function (response) {
                    return on_channel(response.data.data);
                });
            }

            if (fetch_messages) {
                return promise.then(function (channel) {
                    return query_messages(channel).then(function () {
                        return channel;
                    });
                });
            } else {
                return promise;
            }
        };

        var query_channels = function (num_to_fetch, fetch_older) {
            num_to_fetch = num_to_fetch || 0;
            if (channels_queried && !fetch_older) {
                var defer = $q.defer();
                defer.resolve($rootScope.channel_list);
                return defer.promise;
            }

            var params = {
                count: num_to_fetch,
                include_recent_message: 1,
                channel_types: 'net.app.core.pm'
            };

            if (channel_min_id) {
                params.before_id = channel_min_id;
            }

            var url = '/adn-proxy/stream/0/channels';
            return $http({
                method: 'GET',
                url: url,
                params: params
            }).then(function (response) {
                channel_min_id = response.data.meta.min_id;
                var fetched_channels = [];

                angular.forEach(response.data.data, function (value) {
                    var channel = new Channel(value, true);
                    channel_cache[channel.id] = channel;
                    fetched_channels.push(channel);
                });

                User.fetch_pending();

                channels_queried = true;

                $rootScope.channel_list = _.values(channel_cache);

                return fetched_channels;
            });
        };

        var fetch_muted_channels = function () {
            url = '/adn-proxy/stream/0/users/me/channels/muted';

            var params = {
                count: 200,
                include_recent_message: 1,
                channel_types: 'net.app.core.pm'
            };
            return $http({
                method: 'GET',
                url: url,
                params: params
            }).then(function (response) {
                var fetched_channels = [];
                angular.forEach(response.data.data, function (value) {
                    var channel = new Channel(value, true);
                    fetched_channels.push(channel);
                });

                $rootScope.muted_channel_list = _.values(fetched_channels);

                return fetched_channels;
            });
        }

        var update_marker = function (channel, message) {
            // don't push the marker backwards
            var message_id = utils.comparable_id(message);
            var channel_marker_id = channel.marker && utils.comparable_id(channel.marker);
            var should_update = channel_marker_id &&  message_id > channel_marker_id ||
                !channel_marker_id && message_id;
            if (should_update) {
                $http({
                    method: 'POST',
                    url: '/adn-proxy/stream/0/posts/marker',
                    data: {
                        'name': channel.marker.name,
                        'id': message.id
                    }
                }).then(function (response) {
                    channel.marker = response.data.data;
                });
            }
        };

        var display_notification = function (msg) {
            if ($rootScope.user_id !== msg.user.id && window.webkitNotifications) {
                var permission = window.webkitNotifications.checkPermission();
                if (permission === 0) {
                    // notifications are enabled
                    var n = window.webkitNotifications.createNotification(msg.user.avatar_image.url, msg.user.username, msg.text);
                    n.ondisplay = function () {
                        setTimeout(function () {
                            n.cancel();
                        }, 5000);
                    };
                    n.onclick = function () {
                        window.focus();
                        n.cancel();
                    };
                    $(window).unload(function () {
                        n.cancel();
                    });
                    n.show();
                }
            }
        };

        $rootScope.$on('stream_push', function (event, obj) {
            var channel;
            if (obj.meta.type === 'channel') {
                on_channel(obj.data);
            }

            if (obj.meta.type === 'channel_subscription') {
                if (!obj.meta.is_deleted) {
                    on_channel(obj.data.channel);
                } else {
                    channel_unsubscribe(obj.data.channel.id);
                }
            }

            if (obj.meta.type === 'message') {
                channel = channel_cache[obj.data.channel_id];
                if (channel) {
                    if (obj.meta.is_deleted) {
                        channel.messages = _.reject(channel.messages, function (m) {
                            return m.id === obj.data.id;
                        });
                    } else {
                        var msg = new Message(obj.data);
                        if (!channel.recent_message || utils.comparable_id(channel.recent_message) < utils.comparable_id(msg)) {
                            channel.recent_message = msg;
                        }

                        if (channel.marker) {
                            channel.has_unread = utils.comparable_id(channel.recent_message) > utils.comparable_id(channel.marker);
                        } else {
                            channel.has_unread = true;
                        }

                        var last_id = utils.comparable_id(_.last(channel.messages));
                        var current_id = utils.comparable_id(msg);
                        if (!channel.messages) {
                            display_notification(msg);
                            // channel will be created elsewhere with this message
                        } else if (current_id > last_id || channel.messages.length === 0) {
                            display_notification(msg);
                            channel.messages.push(msg);
                        }
                    }
                }
            }

            // only update our own markers
            if (obj.meta.type === 'stream_marker' && obj.meta.user_id === $rootScope.user_id) {
                channel = channel_cache[obj.meta.channel_id];

                if (channel) {
                    channel.marker = obj.data.marker;

                    if (channel.recent_message) {
                        channel.has_unread = utils.comparable_id(channel.recent_message) > utils.comparable_id(channel.marker);
                    } else {
                        channel.has_unread = false;
                    }
                }
            }
        });

        return {
            'get_channel': get_channel,
            'query_channels': query_channels,
            'fetch_muted_channels': fetch_muted_channels,
            'update_marker': update_marker,
            'mute_channel': mute_channel,
            'unmute_channel': unmute_channel
        };
    }]);
})();
<commit_msg>Revert "fix deleting all messages then new msg in channel"<commit_after>/*globals angular */

(function () {
    angular.module('channelState', ['channels', 'messages', 'users', 'socket', 'utils'])
    .factory('channelState', ['$http', '$rootScope', '$q', 'Socket', 'User', 'Channel', 'Message', 'utils', function ($http, $rootScope, $q, Socket, User, Channel, Message, utils) {
        var channel_cache = {};
        var channels_queried = false;
        var channel_min_id;

        var query_messages = function (channel) {
            // TODO: enable this to backfill
            var params = {
                count: $rootScope.message_fetch_size,
                include_deleted: 0,
                include_annotations: 1
            };

            return $http({
                method: 'GET',
                url: '/adn-proxy/stream/0/channels/' + channel.id + '/messages',
                params: params
            }).then(function (response) {
                if (response.data.meta.marker) {
                    channel.marker = response.data.meta.marker;
                }

                var messages = [];

                angular.forEach(response.data.data, function (d) {
                    messages.unshift(new Message(d));
                });

                channel.messages = messages;
            });
        };

        var on_channel = function (data, fetch) {
            var channel;
            // don't add muted channels to the channel cache
            if (data.you_muted) {
                channel = new Channel(data);
            } else {
                channel = channel_cache[data.id];

                if (channel) {
                    channel.update(data);
                } else {
                    channel = channel_cache[data.id] = new Channel(data);
                    $rootScope.channel_list = _.values(channel_cache);
                }
            }

            if (fetch) {
                get_channel(data.id, false);
            }

            return channel;
        };

        var channel_unsubscribe = function (channel_id) {
            delete channel_cache[channel_id];
            $rootScope.channel_list = _.values(channel_cache);
        };

        var mute_channel = function (channel_id) {
            return $http({
                method: 'POST',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/mute'
            }).then(function () {
                channel_unsubscribe(channel_id);
                // clear it from the channel cache, if it was there
                delete channel_cache[channel_id];
                $rootScope.channel_list = _.values(channel_cache);
            });
        };

        var unmute_channel = function (channel_id) {
            var d1 = $http({
                method: 'DELETE',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/mute'
            });
            var d2 = $http({
                method: 'POST',
                url: '/adn-proxy/stream/0/channels/' + channel_id + '/subscribe'
            });

            return $q.all(d1, d2);
        };

        var get_channel = function (channel_id, fetch_messages) {
            var promise;

            if (channel_cache[channel_id]) {
                var channel = channel_cache[channel_id];

                if (channel.messages && channel.messages.length) {
                    fetch_messages = false;
                }

                var defer = $q.defer();
                defer.resolve(channel);
                promise = defer.promise;
            } else {
                promise = $http.get('/adn-proxy/stream/0/channels/' + channel_id).then(function (response) {
                    return on_channel(response.data.data);
                });
            }

            if (fetch_messages) {
                return promise.then(function (channel) {
                    return query_messages(channel).then(function () {
                        return channel;
                    });
                });
            } else {
                return promise;
            }
        };

        var query_channels = function (num_to_fetch, fetch_older) {
            num_to_fetch = num_to_fetch || 0;
            if (channels_queried && !fetch_older) {
                var defer = $q.defer();
                defer.resolve($rootScope.channel_list);
                return defer.promise;
            }

            var params = {
                count: num_to_fetch,
                include_recent_message: 1,
                channel_types: 'net.app.core.pm'
            };

            if (channel_min_id) {
                params.before_id = channel_min_id;
            }

            var url = '/adn-proxy/stream/0/channels';
            return $http({
                method: 'GET',
                url: url,
                params: params
            }).then(function (response) {
                channel_min_id = response.data.meta.min_id;
                var fetched_channels = [];

                angular.forEach(response.data.data, function (value) {
                    var channel = new Channel(value, true);
                    channel_cache[channel.id] = channel;
                    fetched_channels.push(channel);
                });

                User.fetch_pending();

                channels_queried = true;

                $rootScope.channel_list = _.values(channel_cache);

                return fetched_channels;
            });
        };

        var fetch_muted_channels = function () {
            url = '/adn-proxy/stream/0/users/me/channels/muted';

            var params = {
                count: 200,
                include_recent_message: 1,
                channel_types: 'net.app.core.pm'
            };
            return $http({
                method: 'GET',
                url: url,
                params: params
            }).then(function (response) {
                var fetched_channels = [];
                angular.forEach(response.data.data, function (value) {
                    var channel = new Channel(value, true);
                    fetched_channels.push(channel);
                });

                $rootScope.muted_channel_list = _.values(fetched_channels);

                return fetched_channels;
            });
        }

        var update_marker = function (channel, message) {
            // don't push the marker backwards
            var message_id = utils.comparable_id(message);
            var channel_marker_id = channel.marker && utils.comparable_id(channel.marker);
            var should_update = channel_marker_id &&  message_id > channel_marker_id ||
                !channel_marker_id && message_id;
            if (should_update) {
                $http({
                    method: 'POST',
                    url: '/adn-proxy/stream/0/posts/marker',
                    data: {
                        'name': channel.marker.name,
                        'id': message.id
                    }
                }).then(function (response) {
                    channel.marker = response.data.data;
                });
            }
        };

        var display_notification = function (msg) {
            if ($rootScope.user_id !== msg.user.id && window.webkitNotifications) {
                var permission = window.webkitNotifications.checkPermission();
                if (permission === 0) {
                    // notifications are enabled
                    var n = window.webkitNotifications.createNotification(msg.user.avatar_image.url, msg.user.username, msg.text);
                    n.ondisplay = function () {
                        setTimeout(function () {
                            n.cancel();
                        }, 5000);
                    };
                    n.onclick = function () {
                        window.focus();
                        n.cancel();
                    };
                    $(window).unload(function () {
                        n.cancel();
                    });
                    n.show();
                }
            }
        };

        $rootScope.$on('stream_push', function (event, obj) {
            var channel;
            if (obj.meta.type === 'channel') {
                on_channel(obj.data);
            }

            if (obj.meta.type === 'channel_subscription') {
                if (!obj.meta.is_deleted) {
                    on_channel(obj.data.channel);
                } else {
                    channel_unsubscribe(obj.data.channel.id);
                }
            }

            if (obj.meta.type === 'message') {
                channel = channel_cache[obj.data.channel_id];
                if (channel) {
                    if (obj.meta.is_deleted) {
                        channel.messages = _.reject(channel.messages, function (m) {
                            return m.id === obj.data.id;
                        });
                    } else {
                        var msg = new Message(obj.data);
                        if (!channel.recent_message || utils.comparable_id(channel.recent_message) < utils.comparable_id(msg)) {
                            channel.recent_message = msg;
                        }

                        if (channel.marker) {
                            channel.has_unread = utils.comparable_id(channel.recent_message) > utils.comparable_id(channel.marker);
                        } else {
                            channel.has_unread = true;
                        }

                        if (!channel.messages || utils.comparable_id(_.last(channel.messages)) < utils.comparable_id(msg)) {
                            if (channel.messages && channel.messages.length) {
                                channel.messages.push(msg);
                            }
                            display_notification(msg);
                        }
                    }
                }
            }

            // only update our own markers
            if (obj.meta.type === 'stream_marker' && obj.meta.user_id === $rootScope.user_id) {
                channel = channel_cache[obj.meta.channel_id];

                if (channel) {
                    channel.marker = obj.data.marker;

                    if (channel.recent_message) {
                        channel.has_unread = utils.comparable_id(channel.recent_message) > utils.comparable_id(channel.marker);
                    } else {
                        channel.has_unread = false;
                    }
                }
            }
        });

        return {
            'get_channel': get_channel,
            'query_channels': query_channels,
            'fetch_muted_channels': fetch_muted_channels,
            'update_marker': update_marker,
            'mute_channel': mute_channel,
            'unmute_channel': unmute_channel
        };
    }]);
})();
<|endoftext|>