<commit_before>/**
 * @author Stefan Mayer
 */

const https = require('https');
const Rx = require('rx');

const Logger = require('./Logger');

export default class NodeJira {
    constructor(options) {
        this.hostname = options.hostname;
        this.port = options.port;
        this.logger = new Logger(options.logger);
    }

    loginRx(username, password) {
        return Rx.Observable.create((observer) => {
            if (!username || !password) {
                observer.onError('Missing username and/or password');
                observer.onCompleted();
                return;
            }

            const postData = JSON.stringify({
                username,
                password,
            });

            const url = `/rest/auth/1/session`;

            const options = {
                hostname: this.hostname,
                port: this.port,
                path: url,
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Content-Length': Buffer.byteLength(postData),
                },
            };

            this.logger.info('Handling login to Jira', username);

            const req = https.request(options, (res) => {
                if (res.statusCode === 401) {
                    return observer.onError('Username or password wrong');
                } else if (res.statusCode === 403) {
                    return observer.onError('CAPTCHA required');
                } else if (res.statusCode !== 200) {
                    return observer.onError({
                        code: res.statusCode,
                        message: res.statusMessage,
                    });
                }

                observer.onNext({
                    'setCookie': res.headers['set-cookie'],
                });

                res.setEncoding('utf8');
                res.on('data', (data) => {
                    observer.onNext(data);
                });
                res.on('end', () => {
                    observer.onCompleted();
                });
            });

            req.on('error', (e) => {
                this.logger.error('problem with request: ' + e.message);
                observer.onError(e);
                observer.onCompleted();
            });
            req.write(postData);

            req.end();
        }).reduce((prev, current) => {
            if (current.setCookie) {
                prev.setCookie = current.setCookie;
            } else {
                prev.data += current;
            }
            return prev;
        }, {data: ''}).map((data) => {
            return {
                cookie: new Buffer(JSON.stringify(data.setCookie)).toString('base64'),
                data: JSON.parse(data.data),
            };
        }).map((data) => {
            if (data.errorMessages) {
                this.logger.error(data.errorMessages[0]);
                throw new Error(data.errorMessages[0]);
            }
            return data;
        });
    }

    login(username, password) {
        return this.loginRx(username, password).toPromise();
    }
}
<commit_msg>Removed unnecesary functionality from NodeJira<commit_after>/**
 * @author Stefan Mayer
 */

const https = require('https');
const Rx = require('rx');

const Logger = require('./Logger');

export default class NodeJira {
    constructor(options) {
        this.hostname = options.hostname;
        this.port = options.port;
        this.logger = new Logger(options.logger);
    }

    loginRx(username, password) {
        return Rx.Observable.create((observer) => {
            if (!username || !password) {
                observer.onError('Missing username and/or password');
                observer.onCompleted();
                return;
            }

            const postData = JSON.stringify({
                username,
                password,
            });

            const url = `/rest/auth/1/session`;

            const options = {
                hostname: this.hostname,
                port: this.port,
                path: url,
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'Content-Length': Buffer.byteLength(postData),
                },
            };

            this.logger.info('Handling login to Jira', username);

            const req = https.request(options, (res) => {
                if (res.statusCode === 401) {
                    return observer.onError('Username or password wrong');
                } else if (res.statusCode === 403) {
                    return observer.onError('CAPTCHA required');
                } else if (res.statusCode !== 200) {
                    return observer.onError({
                        code: res.statusCode,
                        message: res.statusMessage,
                    });
                }

                observer.onNext({
                    'setCookie': res.headers['set-cookie'],
                });

                res.setEncoding('utf8');
                res.on('data', (data) => {
                    observer.onNext(data);
                });
                res.on('end', () => {
                    observer.onCompleted();
                });
            });

            req.on('error', (e) => {
                this.logger.error('problem with request: ' + e.message);
                observer.onError(e);
                observer.onCompleted();
            });
            req.write(postData);

            req.end();
        }).reduce((prev, current) => {
            if (current.setCookie) {
                prev.setCookie = current.setCookie;
            } else {
                prev.data += current;
            }
            return prev;
        }, {data: ''}).map((data) => {
            return {
                cookie: new Buffer(JSON.stringify(data.setCookie)).toString('base64'),
                data: JSON.parse(data.data),
            };
        });
    }

    login(username, password) {
        return this.loginRx(username, password).toPromise();
    }
}
<|endoftext|>


<commit_before>/**
 * 节点测试
 */
var NodeTestLayer = TestBaseLayer.extend({
	w2: 0,
	h2: 0,
	ctor: function(){
		this._super();
		this.w2 = this.size.width / 2;
		this.h2 = this.size.height / 2;
		var node = new cc.Sprite(res.node152_png);
		this.addChild(node);
		node.setPosition(this.w2 - node.getContentSize().width * 1.3, this.h2);

		var node1 = new cc.Sprite(res.node152_png);
		this.addChild(node1);
		node1.setPosition(this.w2 + node1.getContentSize().width * 1.3,  this.h2);

		// 配置一些信息
		node.name = "node";
		node1.name = "node1";
		this.name = "MainLayer";
		this.setName("MainLayer");

		/// 基础属性
		// 1.1,位置测试
//		this.test_1_1(node, node1);
		// 1.2,大小测试
//		this.test_1_2(node, node1);
		// 1.3,锚点测试
//		this.test_1_3(node, node1);
		// 1.4,层级测试
//		this.test_1_4(node, node1);
		// 1.5,数据和标签测试
		this.test_1_5(node, node1);

		/// 图形属性
		// 2.1 旋转
		// 2.2 缩放
		// 2.3 倾斜
		// 2.4 可见
		// 2.5 透明
		// 2.6 颜色
		// 2.7 渲染

		/// 其他属性
		// 3.1 父/子相关
		// 3.2定时器
		// 3.3 运行状态
		// 3.4 动作管理
		// 3.5 到达顺序

		/// 功能函数
		// 4.1 属性配置
		// 4.2 图形操作
		// 4.3 节点操作
		// 4.4 事件回调
		// 4.5 动作模块
		// 4.6内存管理
		// 4.7计时器
		// 4.8坐标转换
		// 4.9边框区域

	},
	/**
	 * 1.1,位置测试
	 */
	test_1_1: function(node, node1){
		cc.log("===============[位置 Began]===============");
		// 针对【父节点】设置/获取坐标点
		node.setPosition(this.w2, this.h2);
		var position = node.getPosition();
		cc.log("position X: ", position.x, "position Y: ",position.y);

		node.setPositionX(100);
		node.setPositionY(200);
		var posX = node.getPositionX();
		var posY = node.getPositionY();
		cc.log("position X: ", posX, "position Y: ",posY);
		// 规格化设置坐标
		// node.setNormalizedPosition(0.5, 0.5);

		cc.log("-------------------------------------------");

		node1.x = this.w2;
		node1.y = this.h2;
		var position = cc.p(node1.x, node1.y);
		cc.log("position X: ", position.x, "position Y: ",position.y);

		node1.x = 555;
		node1.y = 444;
		var posX = node1.x;
		var posY = node1.y;
		cc.log("position X: ", posX, "position Y: ",posY);

		cc.log("===============[位置 End]=================");
	},
	/**
	 * 1.2,大小测试
	 */
	test_1_2: function(node, node1){
		cc.log("===============[大小 Began]===============");
		var width = node.getContentSize().width;
		var height = node.getContentSize().height;
		cc.log("width : ",width, " , height : ", height);
		// 1. 所有的节点都有大小。 Layer和Scene默认拥有跟【屏幕】一样的大小
		// 2. 设置节点内容的大小, 会影响坐标【位置】。其他举例：LayerColor, 事件
		// 3. 不管节点【缩放或者旋转】等，节点的contentSize是【不会】发生变化的
		node.setContentSize(width/2, height/2);
		cc.log("width2 : ",width, " , height2 : ", height);
		node.setContentSize(cc.size(width/4, height/4));
		cc.log("width4 : ",width, " , height4 : ", height);

		cc.log("-------------------------------------------");

		var width = node1.width;
		var height = node1.height;
		cc.log("width : ",width, " , height : ", height);

		node1.width = width/2;
		node1.height = height/4;
		cc.log("width : ",width, " , height : ", height);

		cc.log("===============[大小 End]=================");
	},
	/**
	 * 1.3,锚点测试
	 */
	test_1_3: function(node, node1){
		cc.log("===============[Block Began]===============");

		// cc.p(0, 0)
		// 1. 是一个【点】，【取值范围】是[0-1]
		// 2. 【决定】了你节点上的【哪个点】定位在你指定的【坐标】上
		// 3. 一些【动作】和【属性】饶这个锚点运作
		// 4. cc.Node 【默认】为 (0, 0), cc.Scene、cc.Layer、cc.Sprite 为(0.5, 0.5)
		var anchor = node.getAnchorPoint();
		cc.log("anchor:", anchor);

		node.setAnchorPoint(0.1, 0.5);
		var anchor = node.getAnchorPoint();
		cc.log("anchor : ", anchor);

		// 【锚点】在当前节点上的【绝对位置】
		cc.log("node.getAnchorPointInPoints() : ", node.getAnchorPointInPoints());

		/// 忽略锚点
		var ignoreAnchor = node.isIgnoreAnchorPointForPosition();
		cc.log("ignoreAnchor", ignoreAnchor);

		node.ignoreAnchorPointForPosition(!ignoreAnchor);
		var ignoreAnchor = node.isIgnoreAnchorPointForPosition();
		cc.log("ignoreAnchor", ignoreAnchor);

		cc.log("-------------------------------------------");

		var anchor = cc.p(node1.anchorX, node1.anchorY);
		cc.log("anchor : ", anchor);

		node1.anchorX = 1;
		node1.anchorY = 1;
		var anchor = cc.p(node1.anchorX, node1.anchorY);
        cc.log("anchor : ", anchor);

        var ignoreAnchor = node1.ignoreAnchor;
        cc.log("ignoreAnchor", ignoreAnchor);

        node1.ignoreAnchor = !ignoreAnchor;
        var ignoreAnchor = node1.ignoreAnchor;
        cc.log("ignoreAnchor", ignoreAnchor);

        // ignoreAnchor
        var node = new cc.Node();

        // cc.Node、 cc.Sprite 为 【false】
        // cc.Layer、cc.Scene  为 【true】
        var scene = new cc.Scene();
        var layer = new cc.Layer();
        var sprite = new cc.Sprite();
        cc.log("node", node.ignoreAnchor);
        cc.log("scene", scene.ignoreAnchor);
        cc.log("layer", layer.ignoreAnchor);
        cc.log("sprite", sprite.ignoreAnchor);

        cc.log("===============[Block End]=================");
	},
	/**
	 * 1.4,层级测试
	 */
	test_1_4: function(node, node1){
		node.setPosition(this.w2, this.h2);
        node1.setVisible(false);

        cc.log("===============[Block Began]===============");

        var tmpNode = new cc.Sprite(res.node152_png);
        tmpNode.setPosition(node.getPositionX() + 50, node.getPositionY() + 50);
        this.addChild(tmpNode);

        // 层级设置
        tmpNode.setLocalZOrder(-1);
        cc.log(" tmpNode.getLocalZOrder() : ", tmpNode.getLocalZOrder());
        cc.log(" tmpNode.getGlobalZOrder() : ", tmpNode.getGlobalZOrder());

        cc.log("-------------------------------------------");

        // tmpNode.zIndex = -1;
        cc.log(" tmpNode.zIndex : ", tmpNode.zIndex);

        cc.log("===============[Block End]=================");
	},
	/**
	 * 1.5,数据和标签测试
	 */
	test_1_5: function(node, node1){
		cc.log("===============[Block Began]===============");
        var OUT_MAN = 1;

        // tag 为【number】类型。
        node.setTag(OUT_MAN);
        cc.log("node.getTag() : ", node.getTag());

        // name 为【string】类型
        node.setName("out man");  // 奥特曼
        cc.log("node.getName() : ", node.getName());

        var userData = {
            name : "out man",
            age : 18
        }

        // 【随意】设置， 一个【数据块】, 【结构体】或者一个【对象】
        node.setUserData(userData);
        cc.log("node.getUserData() :", node.getUserData());

        var tmpNode = new cc.Node();
        tmpNode.setTag(998);

        // 设置一个用户指定的【cocos2d对象】
        node.setUserObject(tmpNode);
        cc.log("node.getObject() : ", node.getUserObject());

        cc.log("-------------------------------------------");

        var OUT_MAN = 1;
        node1.tag = OUT_MAN;
        cc.log("node1.tag : ", node1.tag);

        node1.name = "out man";
        cc.log("node1.name : ", node1.name);

        var userData = {
            name : "out man",
            age : 18
        }
        node1.userData = userData;
        cc.log("node1.userData :", node1.userData);

        var tmpNode = new cc.Node();
        tmpNode.tag = 998 ;
        node1.userObject = tmpNode;
        cc.log("node1.userObject : ", node1.userObject.tag);

        cc.log("===============[Block End]=================");
	}
});

var NodeTestScene = cc.Scene.extend({
	onEnter: function(){
		this._super();

		if(true){
			var layer = new NodeTestLayer();
			this.addChild(layer);
		}
	}
})<commit_msg>2.1旋转<commit_after>/**
 * 节点测试
 */
var NodeTestLayer = TestBaseLayer.extend({
	w2: 0,
	h2: 0,
	ctor: function(){
		this._super();
		this.w2 = this.size.width / 2;
		this.h2 = this.size.height / 2;
		var node = new cc.Sprite(res.node152_png);
		this.addChild(node);
		node.setPosition(this.w2 - node.getContentSize().width * 1.3, this.h2);

		var node1 = new cc.Sprite(res.node152_png);
		this.addChild(node1);
		node1.setPosition(this.w2 + node1.getContentSize().width * 1.3,  this.h2);

		// 配置一些信息
		node.name = "node";
		node1.name = "node1";
		this.name = "MainLayer";
		this.setName("MainLayer");

		/// 基础属性
		// 1.1,位置测试
//		this.test_1_1(node, node1);
		// 1.2,大小测试
//		this.test_1_2(node, node1);
		// 1.3,锚点测试
//		this.test_1_3(node, node1);
		// 1.4,层级测试
//		this.test_1_4(node, node1);
		// 1.5,数据和标签测试
//		this.test_1_5(node, node1);

		/// 图形属性
		// 2.1 旋转
		this.test_2_1(node, node1);
		// 2.2 缩放
		// 2.3 倾斜
		// 2.4 可见
		// 2.5 透明
		// 2.6 颜色
		// 2.7 渲染

		/// 其他属性
		// 3.1 父/子相关
		// 3.2定时器
		// 3.3 运行状态
		// 3.4 动作管理
		// 3.5 到达顺序

		/// 功能函数
		// 4.1 属性配置
		// 4.2 图形操作
		// 4.3 节点操作
		// 4.4 事件回调
		// 4.5 动作模块
		// 4.6内存管理
		// 4.7计时器
		// 4.8坐标转换
		// 4.9边框区域

	},
	/**
	 * 1.1,位置测试
	 */
	test_1_1: function(node, node1){
		cc.log("===============[位置 Began]===============");
		// 针对【父节点】设置/获取坐标点
		node.setPosition(this.w2, this.h2);
		var position = node.getPosition();
		cc.log("position X: ", position.x, "position Y: ",position.y);

		node.setPositionX(100);
		node.setPositionY(200);
		var posX = node.getPositionX();
		var posY = node.getPositionY();
		cc.log("position X: ", posX, "position Y: ",posY);
		// 规格化设置坐标
		// node.setNormalizedPosition(0.5, 0.5);

		cc.log("-------------------------------------------");

		node1.x = this.w2;
		node1.y = this.h2;
		var position = cc.p(node1.x, node1.y);
		cc.log("position X: ", position.x, "position Y: ",position.y);

		node1.x = 555;
		node1.y = 444;
		var posX = node1.x;
		var posY = node1.y;
		cc.log("position X: ", posX, "position Y: ",posY);

		cc.log("===============[位置 End]=================");
	},
	/**
	 * 1.2,大小测试
	 */
	test_1_2: function(node, node1){
		cc.log("===============[大小 Began]===============");
		var width = node.getContentSize().width;
		var height = node.getContentSize().height;
		cc.log("width : ",width, " , height : ", height);
		// 1. 所有的节点都有大小。 Layer和Scene默认拥有跟【屏幕】一样的大小
		// 2. 设置节点内容的大小, 会影响坐标【位置】。其他举例：LayerColor, 事件
		// 3. 不管节点【缩放或者旋转】等，节点的contentSize是【不会】发生变化的
		node.setContentSize(width/2, height/2);
		cc.log("width2 : ",width, " , height2 : ", height);
		node.setContentSize(cc.size(width/4, height/4));
		cc.log("width4 : ",width, " , height4 : ", height);

		cc.log("-------------------------------------------");

		var width = node1.width;
		var height = node1.height;
		cc.log("width : ",width, " , height : ", height);

		node1.width = width/2;
		node1.height = height/4;
		cc.log("width : ",width, " , height : ", height);

		cc.log("===============[大小 End]=================");
	},
	/**
	 * 1.3,锚点测试
	 */
	test_1_3: function(node, node1){
		cc.log("===============[Block Began]===============");

		// cc.p(0, 0)
		// 1. 是一个【点】，【取值范围】是[0-1]
		// 2. 【决定】了你节点上的【哪个点】定位在你指定的【坐标】上
		// 3. 一些【动作】和【属性】饶这个锚点运作
		// 4. cc.Node 【默认】为 (0, 0), cc.Scene、cc.Layer、cc.Sprite 为(0.5, 0.5)
		var anchor = node.getAnchorPoint();
		cc.log("anchor:", anchor);

		node.setAnchorPoint(0.1, 0.5);
		var anchor = node.getAnchorPoint();
		cc.log("anchor : ", anchor);

		// 【锚点】在当前节点上的【绝对位置】
		cc.log("node.getAnchorPointInPoints() : ", node.getAnchorPointInPoints());

		/// 忽略锚点
		var ignoreAnchor = node.isIgnoreAnchorPointForPosition();
		cc.log("ignoreAnchor", ignoreAnchor);

		node.ignoreAnchorPointForPosition(!ignoreAnchor);
		var ignoreAnchor = node.isIgnoreAnchorPointForPosition();
		cc.log("ignoreAnchor", ignoreAnchor);

		cc.log("-------------------------------------------");

		var anchor = cc.p(node1.anchorX, node1.anchorY);
		cc.log("anchor : ", anchor);

		node1.anchorX = 1;
		node1.anchorY = 1;
		var anchor = cc.p(node1.anchorX, node1.anchorY);
        cc.log("anchor : ", anchor);

        var ignoreAnchor = node1.ignoreAnchor;
        cc.log("ignoreAnchor", ignoreAnchor);

        node1.ignoreAnchor = !ignoreAnchor;
        var ignoreAnchor = node1.ignoreAnchor;
        cc.log("ignoreAnchor", ignoreAnchor);

        // ignoreAnchor
        var node = new cc.Node();

        // cc.Node、 cc.Sprite 为 【false】
        // cc.Layer、cc.Scene  为 【true】
        var scene = new cc.Scene();
        var layer = new cc.Layer();
        var sprite = new cc.Sprite();
        cc.log("node", node.ignoreAnchor);
        cc.log("scene", scene.ignoreAnchor);
        cc.log("layer", layer.ignoreAnchor);
        cc.log("sprite", sprite.ignoreAnchor);

        cc.log("===============[Block End]=================");
	},
	/**
	 * 1.4,层级测试
	 */
	test_1_4: function(node, node1){
		node.setPosition(this.w2, this.h2);
        node1.setVisible(false);

        cc.log("===============[Block Began]===============");

        var tmpNode = new cc.Sprite(res.node152_png);
        tmpNode.setPosition(node.getPositionX() + 50, node.getPositionY() + 50);
        this.addChild(tmpNode);

        // 层级设置
        tmpNode.setLocalZOrder(-1);
        cc.log(" tmpNode.getLocalZOrder() : ", tmpNode.getLocalZOrder());
        cc.log(" tmpNode.getGlobalZOrder() : ", tmpNode.getGlobalZOrder());

        cc.log("-------------------------------------------");

        // tmpNode.zIndex = -1;
        cc.log(" tmpNode.zIndex : ", tmpNode.zIndex);

        cc.log("===============[Block End]=================");
	},
	/**
	 * 1.5,数据和标签测试
	 */
	test_1_5: function(node, node1){
		cc.log("===============[Block Began]===============");
        var OUT_MAN = 1;

        // tag 为【number】类型。
        node.setTag(OUT_MAN);
        cc.log("node.getTag() : ", node.getTag());

        // name 为【string】类型
        node.setName("out man");  // 奥特曼
        cc.log("node.getName() : ", node.getName());

        var userData = {
            name : "out man",
            age : 18
        }

        // 【随意】设置， 一个【数据块】, 【结构体】或者一个【对象】
        node.setUserData(userData);
        cc.log("node.getUserData() :", node.getUserData());

        var tmpNode = new cc.Node();
        tmpNode.setTag(998);

        // 设置一个用户指定的【cocos2d对象】
        node.setUserObject(tmpNode);
        cc.log("node.getObject() : ", node.getUserObject());

        cc.log("-------------------------------------------");

        var OUT_MAN = 1;
        node1.tag = OUT_MAN;
        cc.log("node1.tag : ", node1.tag);

        node1.name = "out man";
        cc.log("node1.name : ", node1.name);

        var userData = {
            name : "out man",
            age : 18
        }
        node1.userData = userData;
        cc.log("node1.userData :", node1.userData);

        var tmpNode = new cc.Node();
        tmpNode.tag = 998 ;
        node1.userObject = tmpNode;
        cc.log("node1.userObject : ", node1.userObject.tag);

        cc.log("===============[Block End]=================");
	},
	/**
	 * 2.1 旋转
	 */
	test_2_1: function(node, node1){
		cc.log("===============[Block Began]===============");

//		1. 默认为0度
		node.setRotation(45);
//		node.setRotationX(45);
//		node.setRotationY(45);
		cc.log("node.getRotation() : ", node.getRotation());
		cc.log("node.getRotationX() : ", node.getRotationX());
		cc.log("node.getRotationY() : ", node.getRotationY());

		cc.log("-------------------------------------------");

		node1.rotation = 90;
//			node1.rotationX = 45;
//			node1.rotationY = 45;
		cc.log("node1.rotation : ", node1.rotation);
		cc.log("node1.rotationX : ", node1.rotationX);
		cc.log("node1.rotationY : ", node1.rotationY);

		cc.log("===============[Block End]=================");
	}
});

var NodeTestScene = cc.Scene.extend({
	onEnter: function(){
		this._super();

		if(true){
			var layer = new NodeTestLayer();
			this.addChild(layer);
		}
	}
})<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';

class Parallax extends Component {
  componentDidMount() {
    if (M) {
      const { options } = this.props;
      this.instance = M.Parallax.init(this._parallax, options);
    }
  }

  componentWillUnmount() {
    this.instance && this.instance.destroy();
  }

  render() {
    const { className, imageSrc } = this.props;
    return (

 {
            this._parallax = div;
          }}
        >

    );
  }
}

Parallax.propTypes = {
  className: PropTypes.string,
  /**
   * The image path which will be used for the background of the parallax
   */
  imageSrc: PropTypes.string,
  options: {
    /**
     * The minimum width of the screen, in pixels, where the parallax functionality starts working.
     */
    responsiveThreshold: PropTypes.number
  }
};

Parallax.defaultProps = {
  options: {
    responsiveThreshold: 0
  }
};

export default Parallax;
<commit_msg>Using typeof for consistency<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';

class Parallax extends Component {
  componentDidMount() {
    if (typeof M !== 'undefined') {
      const { options } = this.props;
      this.instance = M.Parallax.init(this._parallax, options);
    }
  }

  componentWillUnmount() {
    this.instance && this.instance.destroy();
  }

  render() {
    const { className, imageSrc } = this.props;
    return (

 {
            this._parallax = div;
          }}
        >

    );
  }
}

Parallax.propTypes = {
  className: PropTypes.string,
  /**
   * The image path which will be used for the background of the parallax
   */
  imageSrc: PropTypes.string,
  options: {
    /**
     * The minimum width of the screen, in pixels, where the parallax functionality starts working.
     */
    responsiveThreshold: PropTypes.number
  }
};

Parallax.defaultProps = {
  options: {
    responsiveThreshold: 0
  }
};

export default Parallax;
<|endoftext|>


<commit_before>/*
 * Namespace: amd/define
 * Null implementation of CommonJS Asynchronous Module Definition (AMD).
 *
 * This null implementation triggers the callback functions registered with
 * define() immediately or throws an error. It does not load missing modules,
 * and does not wait for the definition of all dependencies to trigger the
 * factory callback at a later time.
 *
 * This null implementation is intended to replace requireJS when optimized
 * scripts are combined into a single file by the optimization tool. It expects
 * that all dependencies will be defined before they are required.
 *
 * When a define() function is already available, which supports CommonJS AMD,
 * this module registers itself. This allows to load this module dynamically
 * for unit tests using requireJS. The existing define() method is preserved.
 *
 * Reference:
 * http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition
 *
 * Author: Eric Bréchemier <legalbox@eric.brechemier.name>
 *
 * Copyright:
 * Legal-Box SAS (c) 2010-2011, All Rights Reserved
 *
 * License:
 * BSD License
 * http://creativecommons.org/licenses/BSD/
 *
 * Version:
 * 2011-07-12
 */
/*global define */
(function(){
  // Builder of
  // Closure for amd/define

  var undef,       // undefined value, do not trust global undefined
      cache = {};  // hash of module id => exports

  function define(arg0,arg1,arg2){
    // Function: define([id,] [dependencies,] factory)
    // Define a module.
    //
    // Parameters:
    //   id - string, optional identifier of the module.
    //        This must be an absolute id (not starting with '.' or '..').
    //   dependencies - array of strings, optional, defaults to
    //                  ["require", "exports", "module"]. The dependencies ids
    //                  may be relative to the module id if it is specified.
    //   factory - function, callback which will be called at most once, when
    //             all dependencies are available. If truthy, the return value
    //             of the function will be cached and associated with given id,
    //             unless the id is omitted. For each dependency, the cached
    //             value associated with the dependency id is provided as
    //             argument to the factory callback, in the same order.
    //
    // Note:
    // The dependencies "require", "exports" and "module" have a special
    // meaning, and special values are provided for corresponding arguments:
    //   require - function, require(id) returns the cached value associated
    //             with the id, or throws an error if the module is not loaded.
    //             In this null implementation, any module defined without an
    //             id will be considered as missing.
    //   exports - object, an alternate way to define the return value of the
    //             factory function. In this implementation, the exports is
    //             cached instead of the return value of the factory when
    //             the return value is falsy. It is ignored otherwise.
    //   module - object, with a property 'id' set to the value provided in
    //            the call to define. In this null implementation, in case the
    //            id is omitted, the module.id is undefined. The module object
    //            has no 'uri' property.

    var id = undef,
        dependencies = ["require", "exports", "module"],
        factory,
        i,
        length,
        dependencyId,
        args = [],
        exports = {},
        result;

    switch(arguments.length){
      case 0:   // define()
        return; // nothing to define
      case 1:   // define(factory)
        factory = arg0;
        break;
      case 2:
        if (typeof arg0==='string'){  // define(id,factory)
          id = arg0;
        } else {                      // define(dependencies,factory)
          dependencies = arg0;
        }
        factory = arg1;
        break;
      default: // define(id,dependencies,factory)
        id = arg0;
        dependencies = arg1;
        factory = arg2;
    }

    function fail(message){
      // (private) Function: fail(message)
      // Throw an Error including given message in the description.
      //
      // Parameter:
      //   message - string, message to include in the error description

      throw new Error("Failed to load module id '"+id+"': "+message);
    }

    function getAbsoluteId(relativeId){
      // (private) Function: getAbsoluteId(relativeId)
      // Resolve an identifier relative to the module id.
      //
      // Parameter:
      //   relativeId - string, relative or absolute id
      //
      // Returns:
      //   string, the corresponding absolute id

      if (typeof relativeId !== 'string'){
        fail("string id expected for dependency: '"+relativeId+"'");
      }

      if ( relativeId.charAt(0) !== '.' ) { // starts with '.' or '..'
        return relativeId; // already an absolute id
      }

      var absoluteParts, // array, parts of path of the absolute id
          relativeParts, // array, parts of path of the relative id
          i,
          length,
          pathPart;

      // start with parent module id
      if (typeof id !== 'string'){
        absoluteParts = [];
      } else {
        absoluteParts = id.split('/');
        absoluteParts.pop(); // remove the parent module name at the end
      }

      // relative id of the dependency module
      relativeParts = relativeId.split('/');

      for (i=0, length=relativeParts.length; i<length; i++){
        pathPart = relativeParts[i];
        switch(pathPart){
          case ".":
            // skip
            break;
          case "..":
            // pop one level
            absoluteParts.pop();
            break;
          default:
            absoluteParts.push(pathPart);
        }
      }

      return absoluteParts.join('/');
    }

    function require(relativeId){
      // (private) Function: require(relativeId)
      // Get the cached module matching given id, relative to current module id.
      // An error is thrown in case no module has been cached with given id.
      //
      // Parameter:
      //   relativeId - string, identifier of a dependency, relative to the
      //                identifier of the module who received this require
      //                method as argument.
      //
      // Returns:
      //   any, the exports of the module defined with given id

      var absoluteId = getAbsoluteId(relativeId),
          exports = cache[absoluteId];

      if (exports === undef){
        fail("Module not loaded yet: '"+absoluteId+"'");
      }
      return exports;
    }

    for (i=0, length=dependencies.length; i<length; i++){
      dependencyId = dependencies[i];
      switch (dependencyId){
        case "require":
          args.push(require);
          break;
        case "exports":
          args.push(exports);
          break;
        case "module":
          args.push({id: id});
          break;
        default:
          args.push( require(dependencyId) );
      }
    }

    try {
      result = factory.apply(null,args);
    } catch(e) {
      fail(e);
    }

    if (id !== undef) {
      cache[id] = result? result : exports;
    }
  }

  if (this.define === undef){     // preserve existing define
    this.define = define;         // set this implementation to global define
    define.amd = {};              // claim support for CommonJS AMD
  } else if (typeof this.define.amd === 'object') {
    this.define(function(){       // register this implementation for tests
      return define;
    });
  }

}());
<commit_msg>Made conversion to string explicit based on JSLint comment<commit_after>/*
 * Namespace: amd/define
 * Null implementation of CommonJS Asynchronous Module Definition (AMD).
 *
 * This null implementation triggers the callback functions registered with
 * define() immediately or throws an error. It does not load missing modules,
 * and does not wait for the definition of all dependencies to trigger the
 * factory callback at a later time.
 *
 * This null implementation is intended to replace requireJS when optimized
 * scripts are combined into a single file by the optimization tool. It expects
 * that all dependencies will be defined before they are required.
 *
 * When a define() function is already available, which supports CommonJS AMD,
 * this module registers itself. This allows to load this module dynamically
 * for unit tests using requireJS. The existing define() method is preserved.
 *
 * Reference:
 * http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition
 *
 * Author: Eric Bréchemier <legalbox@eric.brechemier.name>
 *
 * Copyright:
 * Legal-Box SAS (c) 2010-2011, All Rights Reserved
 *
 * License:
 * BSD License
 * http://creativecommons.org/licenses/BSD/
 *
 * Version:
 * 2011-07-12
 */
/*global define */
(function(){
  // Builder of
  // Closure for amd/define

  var undef,       // undefined value, do not trust global undefined
      cache = {};  // hash of module id => exports

  function define(arg0,arg1,arg2){
    // Function: define([id,] [dependencies,] factory)
    // Define a module.
    //
    // Parameters:
    //   id - string, optional identifier of the module.
    //        This must be an absolute id (not starting with '.' or '..').
    //   dependencies - array of strings, optional, defaults to
    //                  ["require", "exports", "module"]. The dependencies ids
    //                  may be relative to the module id if it is specified.
    //   factory - function, callback which will be called at most once, when
    //             all dependencies are available. If truthy, the return value
    //             of the function will be cached and associated with given id,
    //             unless the id is omitted. For each dependency, the cached
    //             value associated with the dependency id is provided as
    //             argument to the factory callback, in the same order.
    //
    // Note:
    // The dependencies "require", "exports" and "module" have a special
    // meaning, and special values are provided for corresponding arguments:
    //   require - function, require(id) returns the cached value associated
    //             with the id, or throws an error if the module is not loaded.
    //             In this null implementation, any module defined without an
    //             id will be considered as missing.
    //   exports - object, an alternate way to define the return value of the
    //             factory function. In this implementation, the exports is
    //             cached instead of the return value of the factory when
    //             the return value is falsy. It is ignored otherwise.
    //   module - object, with a property 'id' set to the value provided in
    //            the call to define. In this null implementation, in case the
    //            id is omitted, the module.id is undefined. The module object
    //            has no 'uri' property.

    var id = undef,
        dependencies = ["require", "exports", "module"],
        factory,
        i,
        length,
        dependencyId,
        args = [],
        exports = {},
        result;

    switch(arguments.length){
      case 0:   // define()
        return; // nothing to define
      case 1:   // define(factory)
        factory = arg0;
        break;
      case 2:
        if (typeof arg0==='string'){  // define(id,factory)
          id = arg0;
        } else {                      // define(dependencies,factory)
          dependencies = arg0;
        }
        factory = arg1;
        break;
      default: // define(id,dependencies,factory)
        id = arg0;
        dependencies = arg1;
        factory = arg2;
    }

    function fail(message){
      // (private) Function: fail(message)
      // Throw an Error including given message in the description.
      //
      // Parameter:
      //   message - string, message to include in the error description

      throw new Error("Failed to load module id '"+String(id)+"': "+message);
    }

    function getAbsoluteId(relativeId){
      // (private) Function: getAbsoluteId(relativeId)
      // Resolve an identifier relative to the module id.
      //
      // Parameter:
      //   relativeId - string, relative or absolute id
      //
      // Returns:
      //   string, the corresponding absolute id

      if (typeof relativeId !== 'string'){
        fail("string id expected for dependency: '"+relativeId+"'");
      }

      if ( relativeId.charAt(0) !== '.' ) { // starts with '.' or '..'
        return relativeId; // already an absolute id
      }

      var absoluteParts, // array, parts of path of the absolute id
          relativeParts, // array, parts of path of the relative id
          i,
          length,
          pathPart;

      // start with parent module id
      if (typeof id !== 'string'){
        absoluteParts = [];
      } else {
        absoluteParts = id.split('/');
        absoluteParts.pop(); // remove the parent module name at the end
      }

      // relative id of the dependency module
      relativeParts = relativeId.split('/');

      for (i=0, length=relativeParts.length; i<length; i++){
        pathPart = relativeParts[i];
        switch(pathPart){
          case ".":
            // skip
            break;
          case "..":
            // pop one level
            absoluteParts.pop();
            break;
          default:
            absoluteParts.push(pathPart);
        }
      }

      return absoluteParts.join('/');
    }

    function require(relativeId){
      // (private) Function: require(relativeId)
      // Get the cached module matching given id, relative to current module id.
      // An error is thrown in case no module has been cached with given id.
      //
      // Parameter:
      //   relativeId - string, identifier of a dependency, relative to the
      //                identifier of the module who received this require
      //                method as argument.
      //
      // Returns:
      //   any, the exports of the module defined with given id

      var absoluteId = getAbsoluteId(relativeId),
          exports = cache[absoluteId];

      if (exports === undef){
        fail("Module not loaded yet: '"+absoluteId+"'");
      }
      return exports;
    }

    for (i=0, length=dependencies.length; i<length; i++){
      dependencyId = dependencies[i];
      switch (dependencyId){
        case "require":
          args.push(require);
          break;
        case "exports":
          args.push(exports);
          break;
        case "module":
          args.push({id: id});
          break;
        default:
          args.push( require(dependencyId) );
      }
    }

    try {
      result = factory.apply(null,args);
    } catch(e) {
      fail(e);
    }

    if (id !== undef) {
      cache[id] = result? result : exports;
    }
  }

  if (this.define === undef){     // preserve existing define
    this.define = define;         // set this implementation to global define
    define.amd = {};              // claim support for CommonJS AMD
  } else if (typeof this.define.amd === 'object') {
    this.define(function(){       // register this implementation for tests
      return define;
    });
  }

}());
<|endoftext|>


<commit_before>// @flow

import * as React from 'react'
import {StyleSheet} from 'react-native'
import glamorous from 'glamorous-native'
import {Card} from '../components/card'
import {Button} from '../components/button'
import deviceInfo from 'react-native-device-info'
import networkInfo from 'react-native-network-info'
import retry from 'p-retry'
import delay from 'delay'
import {reportNetworkProblem} from '../../lib/report-network-problem'
import pkg from '../../../package.json'

const getIpAddress = () =>
  new Promise(resolve => {
    try {
      networkInfo.getIPAddress(resolve)
    } catch (err) {
      resolve(null)
    }
  })

const getPosition = (args = {}) =>
  new Promise(resolve => {
    navigator.geolocation.getCurrentPosition(resolve, () => resolve({}), {
      ...args,
      enableHighAccuracy: true,
      maximumAge: 1000 /*ms*/,
      timeout: 5000 /*ms*/,
    })
  })

const collectData = async () => ({
  id: deviceInfo.getUniqueID(),
  brand: deviceInfo.getBrand(),
  model: deviceInfo.getModel(),
  deviceKind: deviceInfo.getDeviceId(),
  os: deviceInfo.getSystemName(),
  osVersion: deviceInfo.getSystemVersion(),
  appVersion: deviceInfo.getReadableVersion(),
  jsVersion: pkg.version,
  ua: deviceInfo.getUserAgent(),
  ip: await getIpAddress(),
  dateRecorded: new Date().toJSON(),
})

function reportToServer(data) {
  const url =
    'https://www.stolaf.edu/apps/all-about-olaf/index.cfm?fuseaction=Submit'
  return fetch(url, {method: 'POST', body: JSON.stringify(data)})
}

type Props = {}

type State = {
  status: string,
}

export class ReportWifiProblemView extends React.Component<Props, State> {
  state = {
    status: '',
  }

  start = async () => {
    this.setState(() => ({status: 'Collecting data…'}))
    const [position, device] = await Promise.all([getPosition(), collectData()])
    this.setState(() => ({status: 'Reporting data…'}))
    try {
      let data = {position, device, version: 1}
      await retry(() => reportToServer(data), {retries: 10})
      await delay(1000)
      this.setState(() => ({status: 'Thanks!'}))
    } catch (err) {
      reportNetworkProblem(err)
      this.setState(() => ({
        status: 'Apologies; there was an error. Please try again later.',
      }))
    }
  }

  render() {
    return (
      <Card style={styles.card}>
        <Title selectable={true}>Report a Wi-Fi Problem</Title>
        <Description selectable={true}>
          If you are having an issue connecting to any of the St. Olaf College
          Wi-Fi networks, please tap the button below.
        </Description>
        <Description selectable={true}>
          This information is anonymous, and we do not collect usernames. We
          will record your current location and some general information about
          the device you are using, then send it to a server that IT maintains.
        </Description>
        <Description selectable={true}>
          The networking team can then use this information to identify where
          people are having issues!
        </Description>
        <Button
          disabled={this.state.status !== ''}
          onPress={this.start}
          title={this.state.status || 'Report'}
        />
      </Card>
    )
  }
}

const Title = glamorous.text({
  fontWeight: '700',
  fontSize: 16,
  marginVertical: 15,
})

const Description = glamorous.text({
  fontSize: 14,
  marginBottom: 15,
  justifyContent: 'space-between',
  textAlign: 'center',
})

const styles = StyleSheet.create({
  card: {
    paddingHorizontal: 20,
    paddingVertical: 5,
  },
})
<commit_msg>move status messages into a state machine<commit_after>// @flow

import * as React from 'react'
import {StyleSheet} from 'react-native'
import glamorous from 'glamorous-native'
import {Card} from '../components/card'
import {Button} from '../components/button'
import deviceInfo from 'react-native-device-info'
import networkInfo from 'react-native-network-info'
import retry from 'p-retry'
import delay from 'delay'
import {reportNetworkProblem} from '../../lib/report-network-problem'
import pkg from '../../../package.json'

const getIpAddress = () =>
  new Promise(resolve => {
    try {
      networkInfo.getIPAddress(resolve)
    } catch (err) {
      resolve(null)
    }
  })

const getPosition = (args = {}) =>
  new Promise(resolve => {
    navigator.geolocation.getCurrentPosition(resolve, () => resolve({}), {
      ...args,
      enableHighAccuracy: true,
      maximumAge: 1000 /*ms*/,
      timeout: 5000 /*ms*/,
    })
  })

const collectData = async () => ({
  id: deviceInfo.getUniqueID(),
  brand: deviceInfo.getBrand(),
  model: deviceInfo.getModel(),
  deviceKind: deviceInfo.getDeviceId(),
  os: deviceInfo.getSystemName(),
  osVersion: deviceInfo.getSystemVersion(),
  appVersion: deviceInfo.getReadableVersion(),
  jsVersion: pkg.version,
  ua: deviceInfo.getUserAgent(),
  ip: await getIpAddress(),
  dateRecorded: new Date().toJSON(),
})

function reportToServer(data) {
  const url =
    'https://www.stolaf.edu/apps/all-about-olaf/index.cfm?fuseaction=Submit'
  return fetch(url, {method: 'POST', body: JSON.stringify(data)})
}

type Props = {}

type State = {
  error: ?string,
  status: 'init' | 'collecting' | 'reporting' | 'done' | 'error',
}

export class ReportWifiProblemView extends React.Component<Props, State> {
  state = {
    error: null,
    status: 'init',
  }

  start = async () => {
    this.setState(() => ({status: 'collecting', error: ''}))
    const [position, device] = await Promise.all([getPosition(), collectData()])
    this.setState(() => ({status: 'reporting'}))
    try {
      let data = {position, device, version: 1}
      await retry(() => reportToServer(data), {retries: 10})
      await delay(1000)
      this.setState(() => ({status: 'done'}))
    } catch (err) {
      reportNetworkProblem(err)
      this.setState(() => ({
        error: 'Apologies; there was an error. Please try again later.',
        status: 'error',
      }))
    }
  }

  render() {
    const buttonEnabled =
      this.state.status === 'init' || this.state.status === 'error'

    let buttonMessage = 'Error'
    if (this.state.status === 'init') {
      buttonMessage = 'Report'
    } else if (this.state.status === 'collecting') {
      buttonMessage = 'Collecting data…'
    } else if (this.state.status === 'reporting') {
      buttonMessage = 'Reporting data…'
    } else if (this.state.status === 'done') {
      buttonMessage = 'Thanks!'
    } else if (this.state.status === 'error') {
      buttonMessage = 'Try again?'
    } else {
      ;(this.state.status: empty)
    }

    return (
      <Card style={styles.card}>
        <Title selectable={true}>Report a Wi-Fi Problem</Title>
        <Description selectable={true}>
          If you are having an issue connecting to any of the St. Olaf College
          Wi-Fi networks, please tap the button below.
        </Description>
        <Description selectable={true}>
          This information is anonymous, and we do not collect usernames. We
          will record your current location and some general information about
          the device you are using, then send it to a server that IT maintains.
        </Description>
        <Description selectable={true}>
          The networking team can then use this information to identify where
          people are having issues!
        </Description>
        <Button
          disabled={!buttonEnabled}
          onPress={this.start}
          title={buttonMessage}
        />
      </Card>
    )
  }
}

const Title = glamorous.text({
  fontWeight: '700',
  fontSize: 16,
  marginVertical: 15,
})

const Description = glamorous.text({
  fontSize: 14,
  marginBottom: 15,
  justifyContent: 'space-between',
  textAlign: 'center',
})

const styles = StyleSheet.create({
  card: {
    paddingHorizontal: 20,
    paddingVertical: 5,
  },
})
<|endoftext|>


<commit_before>/*
 angularAMD v<%= cvars.proj_version %>
 (c) 2013-2014 Marcos Lin https://github.com/marcoslin/
 License: MIT
*/

define(function () {
    'use strict';
    var bootstrapped = false,

        // Used in .bootstrap
        app_name,
        orig_app,
        alt_app,
        run_injector,
        config_injector,
        app_cached_providers = {},

        // Used in setAlternateAngular(), alt_angular is set to become angular.module
        orig_angular,
        alt_angular,

        // Object that wrap the provider methods that enables lazy loading
        onDemandLoader = {},
        preBootstrapLoaderQueue = [],

        // Used in setAlternateAngular() and .processQueue
        alternate_modules = {},
        alternate_modules_tracker = {},
        alternate_queue = [];

    // Private method to check if angularAMD has been initialized
    function checkBootstrapped() {
        if ( !bootstrapped ) {
            throw new Error('angularAMD not initialized.  Need to call angularAMD.bootstrap(app) first.');
        }
    }

    /**
     * Create an alternate angular so that subsequent call to angular.module will queue up
     * the module created for later processing via the .processQueue method.
     *
     * This delaying processing is needed as angular does not recognize any newly created
     * module after angular.bootstrap has ran.  The only way to add new objects to angular
     * post bootstrap is using cached provider.
     *
     * Once the modules has been queued, processQueue would then use each module's _invokeQueue
     * and _runBlock to recreate object using cached $provider.  In essence, creating a duplicate
     * object into the current ng-app.  As result, if there are subsequent call to retrieve the
     * module post processQueue, it would retrieve a module that is not integrated into the ng-app.
     *
     * Therefore, any subsequent to call to angular.module after processQueue should return undefined
     * to prevent obtaining a duplicated object.  However, it is critical that angular.module return
     * appropriate object *during* processQueue.
     */
    function setAlternateAngular() {
        // This method cannot be called more than once
        if (alt_angular) {
            throw new Error('setAlternateAngular can only be called once.');
        } else {
            alt_angular = {};
        }

        // Make sure that bootstrap has been called
        checkBootstrapped();

        // Create a a copy of orig_angular with on demand loading capability
        orig_angular.extend(alt_angular, orig_angular);

        // Custom version of angular.module used as cache
        alt_angular.module = function (name, requires) {
            if (typeof requires === 'undefined') {
                // Return module from alternate_modules if it was created using the alt_angular
                if (alternate_modules_tracker.hasOwnProperty(name)) {
                    return alternate_modules[name];
                } else {
                    return orig_angular.module(name);
                }
            } else {
                var orig_mod = orig_angular.module.apply(null, arguments),
                    item = { name: name, module: orig_mod};
                alternate_queue.push(item);
                orig_angular.extend(orig_mod, onDemandLoader);

                /*
                Use `alternate_modules_tracker` to track which module has been created by alt_angular
                but use `alternate_modules` to cache the module created.  This is to simplify the
                removal of cached modules after .processQueue.
                */
                alternate_modules_tracker[name] = true;
                alternate_modules[name] = orig_mod;

                // Return created module
                return orig_mod;
            }
        };

        window.angular = alt_angular;
    }

    // Constructor
    function AngularAMD() {}

    /**
     * Helper function to generate angular's $routeProvider.route.  'config' input param must be an object.
     *
     * Populate the resolve attribute using either 'controllerUrl' or 'controller'.  If 'controllerUrl'
     * is passed, it will attempt to load the Url using requirejs and remove the attribute from the config
     * object.  Otherwise, it will attempt to populate resolve by loading what's been passed in 'controller'.
     * If neither is passed, resolve is not populated.
     *
     * This function works as a pass-through, meaning what ever is passed in as 'config' will be returned,
     * except for 'controllerUrl' attribute.
     *
     */
    AngularAMD.prototype.route = function (config) {
        // Initialization not necessary to call this method.
        var load_controller;

        /*
        If `controllerUrl` is provided, load the provided Url using requirejs.  If `controller` is not provided
        but `controllerUrl` is, assume that module to be loaded will return a function to act as controller.

        Otherwise, attempt to load the controller using the controller name.  In the later case, controller name
        is expected to be defined as one of 'paths' in main.js.
        */
        if ( config.hasOwnProperty('controllerUrl') ) {
            load_controller = config.controllerUrl;
            delete config.controllerUrl;
            if (typeof config.controller === 'undefined') {
                // Only controllerUrl is defined.  Attempt to set the controller to return value of package loaded.
                config.controller = [
                    '$scope', '__AAMDCtrl', '$injector',
                    function ($scope, __AAMDCtrl, $injector) {
                        if (typeof __AAMDCtrl !== 'undefined' ) {
                            $injector.invoke(__AAMDCtrl, this, { '$scope': $scope });
                        }
                    }
                ];
            }
        } else if (typeof config.controller === 'string') {
            load_controller = config.controller;
        }

        // If controller needs to be loaded, append to the resolve property
        if (load_controller) {
            var resolve = config.resolve || {};
            resolve['__AAMDCtrl'] = ['$q', '$rootScope', function ($q, $rootScope) { // jshint ignore:line
                var defer = $q.defer();
                require([load_controller], function (ctrl) {
                    defer.resolve(ctrl);
                    $rootScope.$apply();
                });
                return defer.promise;
            }];
            config.resolve = resolve;
        }

        return config;
    };

    /**
     * Expose name of the app that has been bootstrapped
     */
    AngularAMD.prototype.appname = function () {
        checkBootstrapped();
        return app_name;
    };

    /**
     * Recreate the modules created by alternate angular in ng-app using cached $provider.
     * As AMD loader does not guarantee the order of dependency in a require([...],...)
     * clause, user must make sure that dependecies are clearly setup in shim in order
     * for this to work.
     *
     * HACK ALERT:
     * This method relay on inner working of angular.module code, and access _invokeQueue
     * and _runBlock private variable.  Must test carefully with each release of angular.
     *
     * As of AngularJS 1.3.x, there is new _configBlocks that get populated with configuration
     * blocks, thus replacing the need for "provider === '$injector' && method === 'invoke'"
     * logic.
     */
    AngularAMD.prototype.processQueue = function () {
        checkBootstrapped();

        if (typeof alt_angular === 'undefined') {
            throw new Error('Alternate angular not set.  Make sure that `enable_ngload` option has been set when calling angularAMD.bootstrap');
        }

        // Process alternate queue in FIFO fashion
        function processRunBlock(block) {
            //console.info('"' + item.name + '": executing run block: ', run_block);
            run_injector.invoke(block);
        }

        while (alternate_queue.length) {
            var item = alternate_queue.shift(),
                invokeQueue = item.module._invokeQueue,
                y;

            // Setup the providers define in the module
            // console.info('invokeQueue: ', invokeQueue);
            for (y = 0; y < invokeQueue.length; y += 1) {
                var q = invokeQueue[y],
                    provider = q[0],
                    method = q[1],
                    args = q[2];

                // Make sure that provider exists.
                if (app_cached_providers.hasOwnProperty(provider)) {
                    var cachedProvider;
                    if (provider === '$injector' && method === 'invoke') {
                        cachedProvider = config_injector;
                    } else {
                        cachedProvider = app_cached_providers[provider];
                    }
                    // console.info('"' + item.name + '": applying ' + provider + '.' + method + ' for args: ', args);
                    cachedProvider[method].apply(null, args);
                } else {
                    // Make sure that console exists before calling it
                    if ( window.console ) {
                        window.console.error('"' + provider + '" not found!!!');
                    }
                }
            }

            /*
             As of AngularJS 1.3.x, the config block are now stored in a new _configBlocks private
             variable.  Loop through the list and invoke the config block with config_injector
             */
            if (item.module._configBlocks) {
                var configBlocks = item.module._configBlocks;

                // console.info('configBlock: ', configBlocks);
                for (y = 0; y < configBlocks.length; y += 1) {
                    var cf = configBlocks[y],
                        cf_method = cf[1],
                        cf_args = cf[2];

                    config_injector[cf_method].apply(null, cf_args);
                }
            }

            // Execute the run block of the module
            if (item.module._runBlocks) {
                angular.forEach(item.module._runBlocks, processRunBlock);
            }

            /*
            Clear the cached modules created by alt_angular so that subsequent call to
            angular.module will return undefined.
            */
            alternate_modules = {};
        }

    };

    /**
     * Return cached app provider
     */
    AngularAMD.prototype.getCachedProvider = function (provider_name) {
        checkBootstrapped();
        // Hack used for unit testing that orig_angular has been captured
        var cachedProvider;

        switch(provider_name) {
            case '__orig_angular':
                cachedProvider = orig_angular;
                break;
            case '__alt_angular':
                cachedProvider = alt_angular;
                break;
            case '__orig_app':
                cachedProvider = orig_app;
                break;
            case '__alt_app':
                cachedProvider = alt_app;
                break;
            default:
                cachedProvider = app_cached_providers[provider_name];
        }

        return cachedProvider;
    };

    /**
     * Create inject function that uses cached $injector.
     * Designed primarly to be used during unit testing.
     */
    AngularAMD.prototype.inject = function () {
        checkBootstrapped();
        return run_injector.invoke.apply(null, arguments);
    };

    /**
     * Create config function that uses cached config_injector.
     * Designed to simulate app.config.
     */
    AngularAMD.prototype.config = function () {
        checkBootstrapped();
        return config_injector.invoke.apply(null, arguments);
    };

    /**
     * Reset angularAMD for resuse
     */
    AngularAMD.prototype.reset = function () {
        if (typeof orig_angular === 'undefined') {
            return;
        }

        // Restore original angular instance
        window.angular = orig_angular;

        // Clear stored app
        orig_app = undefined;
        alt_app = undefined;

        // Clear original angular
        alt_angular = undefined;
        orig_angular = undefined;
        onDemandLoader = {};
        preBootstrapLoaderQueue = [];

        // Clear private variables
        alternate_queue = [];
        app_name = undefined;
        run_injector = undefined;
        config_injector = undefined;
        app_cached_providers = {};

        // Clear bootstrap flag but there is no way to un-bootstrap AngularJS
        bootstrapped = false;
    };

    /**
     * Initialization of angularAMD that bootstraps AngularJS.  The objective is to cache the
     * $provider and $injector from the app to be used later.
     *
     * enable_ngload:
     */
    AngularAMD.prototype.bootstrap = function (app, enable_ngload, elem) {
        // Prevent bootstrap from being called multiple times
        if (bootstrapped) {
            throw Error('bootstrap can only be called once.');
        }

        if (typeof enable_ngload === 'undefined') {
            enable_ngload = true;
        }

        // Store reference to original angular and app
        orig_angular = angular;

        // Create new version of app
        orig_app = app;
        alt_app = {};
        orig_angular.extend(alt_app, orig_app);

        // Determine element to bootstrap angular
        elem = elem || document.documentElement;

        // Cache provider needed
        app.config(
            ['$controllerProvider', '$compileProvider', '$filterProvider', '$animateProvider', '$provide', '$injector', function (controllerProvider, compileProvider, filterProvider, animateProvider, provide, injector) {
                // Cache Providers
                config_injector = injector;
                app_cached_providers = {
                    $controllerProvider: controllerProvider,
                    $compileProvider: compileProvider,
                    $filterProvider: filterProvider,
                    $animateProvider: animateProvider,
                    $provide: provide
                };

                // Substitue provider methods from app call the cached provider
                angular.extend(onDemandLoader, {
                    provider : function(name, constructor) {
                        provide.provider(name, constructor);
                        return this;
                    },
                    controller : function(name, constructor) {
                        controllerProvider.register(name, constructor);
                        return this;
                    },
                    directive : function(name, constructor) {
                        compileProvider.directive(name, constructor);
                        return this;
                    },
                    filter : function(name, constructor) {
                        filterProvider.register(name, constructor);
                        return this;
                    },
                    factory : function(name, constructor) {
                        // console.log('onDemandLoader.factory called for ' + name);
                        provide.factory(name, constructor);
                        return this;
                    },
                    service : function(name, constructor) {
                        provide.service(name, constructor);
                        return this;
                    },
                    constant : function(name, constructor) {
                        provide.constant(name, constructor);
                        return this;
                    },
                    value : function(name, constructor) {
                        provide.value(name, constructor);
                        return this;
                    },
                    animation: angular.bind(animateProvider, animateProvider.register)
                });
                angular.extend(alt_app, onDemandLoader);

            }]
        );

        // Get the injector for the app
        app.run(['$injector', function ($injector) {
            // $injector must be obtained in .run instead of .config
            run_injector = $injector;
            app_cached_providers.$injector = run_injector;
        }]);

        // Store the app name needed by .bootstrap function.
        app_name = app.name;

        // If there are angular provider recipe queued up, process it
        if (preBootstrapLoaderQueue.length > 0) {
            for (var iq = 0; iq < preBootstrapLoaderQueue.length; iq += 1) {
                var item = preBootstrapLoaderQueue[iq];
                orig_app[item.recipe](item.name, item.constructor);
            }
            preBootstrapLoaderQueue = [];
        }

        // Create a app.register object to keep backward compatibility
        orig_app.register = onDemandLoader;

        // Bootstrap Angular
        orig_angular.element(document).ready(function () {
            orig_angular.bootstrap(elem, [app_name]);
            // Indicate bootstrap completed
            bootstrapped = true;

            // Replace angular.module
            if (enable_ngload) {
                //console.info('Setting alternate angular');
                setAlternateAngular();
            }
        });

        // Return app
        return alt_app;
    };

    // Define provider
    function executeProvider(providerRecipe) {
        return function (name, constructor) {
            if (bootstrapped) {
                onDemandLoader[providerRecipe](name, constructor);
            } else {
                // Queue up the request to be used during .bootstrap
                preBootstrapLoaderQueue.push({
                    'recipe': providerRecipe,
                    'name': name,
                    'constructor': constructor
                });
            }
            return this;
        };
    }

    // .provider
    AngularAMD.prototype.provider = executeProvider('provider');
    // .controller
    AngularAMD.prototype.controller = executeProvider('controller');
    // .directive
    AngularAMD.prototype.directive = executeProvider('directive');
    // .filter
    AngularAMD.prototype.filter = executeProvider('filter');
    // .factory
    AngularAMD.prototype.factory = executeProvider('factory');
    // .service
    AngularAMD.prototype.service = executeProvider('service');
    // .constant
    AngularAMD.prototype.constant = executeProvider('constant');
    // .value
    AngularAMD.prototype.value = executeProvider('value');
    // .animation
    AngularAMD.prototype.animation = executeProvider('animation');

    // Create a new instance and return
    return new AngularAMD();

});
<commit_msg>Naming the define() AMD module  <commit_after>/*
 angularAMD v<%= cvars.proj_version %>
 (c) 2013-2014 Marcos Lin https://github.com/marcoslin/
 License: MIT
*/

define('angularAMD', function () {
    'use strict';
    var bootstrapped = false,

        // Used in .bootstrap
        app_name,
        orig_app,
        alt_app,
        run_injector,
        config_injector,
        app_cached_providers = {},

        // Used in setAlternateAngular(), alt_angular is set to become angular.module
        orig_angular,
        alt_angular,

        // Object that wrap the provider methods that enables lazy loading
        onDemandLoader = {},
        preBootstrapLoaderQueue = [],

        // Used in setAlternateAngular() and .processQueue
        alternate_modules = {},
        alternate_modules_tracker = {},
        alternate_queue = [];

    // Private method to check if angularAMD has been initialized
    function checkBootstrapped() {
        if ( !bootstrapped ) {
            throw new Error('angularAMD not initialized.  Need to call angularAMD.bootstrap(app) first.');
        }
    }

    /**
     * Create an alternate angular so that subsequent call to angular.module will queue up
     * the module created for later processing via the .processQueue method.
     *
     * This delaying processing is needed as angular does not recognize any newly created
     * module after angular.bootstrap has ran.  The only way to add new objects to angular
     * post bootstrap is using cached provider.
     *
     * Once the modules has been queued, processQueue would then use each module's _invokeQueue
     * and _runBlock to recreate object using cached $provider.  In essence, creating a duplicate
     * object into the current ng-app.  As result, if there are subsequent call to retrieve the
     * module post processQueue, it would retrieve a module that is not integrated into the ng-app.
     *
     * Therefore, any subsequent to call to angular.module after processQueue should return undefined
     * to prevent obtaining a duplicated object.  However, it is critical that angular.module return
     * appropriate object *during* processQueue.
     */
    function setAlternateAngular() {
        // This method cannot be called more than once
        if (alt_angular) {
            throw new Error('setAlternateAngular can only be called once.');
        } else {
            alt_angular = {};
        }

        // Make sure that bootstrap has been called
        checkBootstrapped();

        // Create a a copy of orig_angular with on demand loading capability
        orig_angular.extend(alt_angular, orig_angular);

        // Custom version of angular.module used as cache
        alt_angular.module = function (name, requires) {
            if (typeof requires === 'undefined') {
                // Return module from alternate_modules if it was created using the alt_angular
                if (alternate_modules_tracker.hasOwnProperty(name)) {
                    return alternate_modules[name];
                } else {
                    return orig_angular.module(name);
                }
            } else {
                var orig_mod = orig_angular.module.apply(null, arguments),
                    item = { name: name, module: orig_mod};
                alternate_queue.push(item);
                orig_angular.extend(orig_mod, onDemandLoader);

                /*
                Use `alternate_modules_tracker` to track which module has been created by alt_angular
                but use `alternate_modules` to cache the module created.  This is to simplify the
                removal of cached modules after .processQueue.
                */
                alternate_modules_tracker[name] = true;
                alternate_modules[name] = orig_mod;

                // Return created module
                return orig_mod;
            }
        };

        window.angular = alt_angular;
    }

    // Constructor
    function AngularAMD() {}

    /**
     * Helper function to generate angular's $routeProvider.route.  'config' input param must be an object.
     *
     * Populate the resolve attribute using either 'controllerUrl' or 'controller'.  If 'controllerUrl'
     * is passed, it will attempt to load the Url using requirejs and remove the attribute from the config
     * object.  Otherwise, it will attempt to populate resolve by loading what's been passed in 'controller'.
     * If neither is passed, resolve is not populated.
     *
     * This function works as a pass-through, meaning what ever is passed in as 'config' will be returned,
     * except for 'controllerUrl' attribute.
     *
     */
    AngularAMD.prototype.route = function (config) {
        // Initialization not necessary to call this method.
        var load_controller;

        /*
        If `controllerUrl` is provided, load the provided Url using requirejs.  If `controller` is not provided
        but `controllerUrl` is, assume that module to be loaded will return a function to act as controller.

        Otherwise, attempt to load the controller using the controller name.  In the later case, controller name
        is expected to be defined as one of 'paths' in main.js.
        */
        if ( config.hasOwnProperty('controllerUrl') ) {
            load_controller = config.controllerUrl;
            delete config.controllerUrl;
            if (typeof config.controller === 'undefined') {
                // Only controllerUrl is defined.  Attempt to set the controller to return value of package loaded.
                config.controller = [
                    '$scope', '__AAMDCtrl', '$injector',
                    function ($scope, __AAMDCtrl, $injector) {
                        if (typeof __AAMDCtrl !== 'undefined' ) {
                            $injector.invoke(__AAMDCtrl, this, { '$scope': $scope });
                        }
                    }
                ];
            }
        } else if (typeof config.controller === 'string') {
            load_controller = config.controller;
        }

        // If controller needs to be loaded, append to the resolve property
        if (load_controller) {
            var resolve = config.resolve || {};
            resolve['__AAMDCtrl'] = ['$q', '$rootScope', function ($q, $rootScope) { // jshint ignore:line
                var defer = $q.defer();
                require([load_controller], function (ctrl) {
                    defer.resolve(ctrl);
                    $rootScope.$apply();
                });
                return defer.promise;
            }];
            config.resolve = resolve;
        }

        return config;
    };

    /**
     * Expose name of the app that has been bootstrapped
     */
    AngularAMD.prototype.appname = function () {
        checkBootstrapped();
        return app_name;
    };

    /**
     * Recreate the modules created by alternate angular in ng-app using cached $provider.
     * As AMD loader does not guarantee the order of dependency in a require([...],...)
     * clause, user must make sure that dependecies are clearly setup in shim in order
     * for this to work.
     *
     * HACK ALERT:
     * This method relay on inner working of angular.module code, and access _invokeQueue
     * and _runBlock private variable.  Must test carefully with each release of angular.
     *
     * As of AngularJS 1.3.x, there is new _configBlocks that get populated with configuration
     * blocks, thus replacing the need for "provider === '$injector' && method === 'invoke'"
     * logic.
     */
    AngularAMD.prototype.processQueue = function () {
        checkBootstrapped();

        if (typeof alt_angular === 'undefined') {
            throw new Error('Alternate angular not set.  Make sure that `enable_ngload` option has been set when calling angularAMD.bootstrap');
        }

        // Process alternate queue in FIFO fashion
        function processRunBlock(block) {
            //console.info('"' + item.name + '": executing run block: ', run_block);
            run_injector.invoke(block);
        }

        while (alternate_queue.length) {
            var item = alternate_queue.shift(),
                invokeQueue = item.module._invokeQueue,
                y;

            // Setup the providers define in the module
            // console.info('invokeQueue: ', invokeQueue);
            for (y = 0; y < invokeQueue.length; y += 1) {
                var q = invokeQueue[y],
                    provider = q[0],
                    method = q[1],
                    args = q[2];

                // Make sure that provider exists.
                if (app_cached_providers.hasOwnProperty(provider)) {
                    var cachedProvider;
                    if (provider === '$injector' && method === 'invoke') {
                        cachedProvider = config_injector;
                    } else {
                        cachedProvider = app_cached_providers[provider];
                    }
                    // console.info('"' + item.name + '": applying ' + provider + '.' + method + ' for args: ', args);
                    cachedProvider[method].apply(null, args);
                } else {
                    // Make sure that console exists before calling it
                    if ( window.console ) {
                        window.console.error('"' + provider + '" not found!!!');
                    }
                }
            }

            /*
             As of AngularJS 1.3.x, the config block are now stored in a new _configBlocks private
             variable.  Loop through the list and invoke the config block with config_injector
             */
            if (item.module._configBlocks) {
                var configBlocks = item.module._configBlocks;

                // console.info('configBlock: ', configBlocks);
                for (y = 0; y < configBlocks.length; y += 1) {
                    var cf = configBlocks[y],
                        cf_method = cf[1],
                        cf_args = cf[2];

                    config_injector[cf_method].apply(null, cf_args);
                }
            }

            // Execute the run block of the module
            if (item.module._runBlocks) {
                angular.forEach(item.module._runBlocks, processRunBlock);
            }

            /*
            Clear the cached modules created by alt_angular so that subsequent call to
            angular.module will return undefined.
            */
            alternate_modules = {};
        }

    };

    /**
     * Return cached app provider
     */
    AngularAMD.prototype.getCachedProvider = function (provider_name) {
        checkBootstrapped();
        // Hack used for unit testing that orig_angular has been captured
        var cachedProvider;

        switch(provider_name) {
            case '__orig_angular':
                cachedProvider = orig_angular;
                break;
            case '__alt_angular':
                cachedProvider = alt_angular;
                break;
            case '__orig_app':
                cachedProvider = orig_app;
                break;
            case '__alt_app':
                cachedProvider = alt_app;
                break;
            default:
                cachedProvider = app_cached_providers[provider_name];
        }

        return cachedProvider;
    };

    /**
     * Create inject function that uses cached $injector.
     * Designed primarly to be used during unit testing.
     */
    AngularAMD.prototype.inject = function () {
        checkBootstrapped();
        return run_injector.invoke.apply(null, arguments);
    };

    /**
     * Create config function that uses cached config_injector.
     * Designed to simulate app.config.
     */
    AngularAMD.prototype.config = function () {
        checkBootstrapped();
        return config_injector.invoke.apply(null, arguments);
    };

    /**
     * Reset angularAMD for resuse
     */
    AngularAMD.prototype.reset = function () {
        if (typeof orig_angular === 'undefined') {
            return;
        }

        // Restore original angular instance
        window.angular = orig_angular;

        // Clear stored app
        orig_app = undefined;
        alt_app = undefined;

        // Clear original angular
        alt_angular = undefined;
        orig_angular = undefined;
        onDemandLoader = {};
        preBootstrapLoaderQueue = [];

        // Clear private variables
        alternate_queue = [];
        app_name = undefined;
        run_injector = undefined;
        config_injector = undefined;
        app_cached_providers = {};

        // Clear bootstrap flag but there is no way to un-bootstrap AngularJS
        bootstrapped = false;
    };

    /**
     * Initialization of angularAMD that bootstraps AngularJS.  The objective is to cache the
     * $provider and $injector from the app to be used later.
     *
     * enable_ngload:
     */
    AngularAMD.prototype.bootstrap = function (app, enable_ngload, elem) {
        // Prevent bootstrap from being called multiple times
        if (bootstrapped) {
            throw Error('bootstrap can only be called once.');
        }

        if (typeof enable_ngload === 'undefined') {
            enable_ngload = true;
        }

        // Store reference to original angular and app
        orig_angular = angular;

        // Create new version of app
        orig_app = app;
        alt_app = {};
        orig_angular.extend(alt_app, orig_app);

        // Determine element to bootstrap angular
        elem = elem || document.documentElement;

        // Cache provider needed
        app.config(
            ['$controllerProvider', '$compileProvider', '$filterProvider', '$animateProvider', '$provide', '$injector', function (controllerProvider, compileProvider, filterProvider, animateProvider, provide, injector) {
                // Cache Providers
                config_injector = injector;
                app_cached_providers = {
                    $controllerProvider: controllerProvider,
                    $compileProvider: compileProvider,
                    $filterProvider: filterProvider,
                    $animateProvider: animateProvider,
                    $provide: provide
                };

                // Substitue provider methods from app call the cached provider
                angular.extend(onDemandLoader, {
                    provider : function(name, constructor) {
                        provide.provider(name, constructor);
                        return this;
                    },
                    controller : function(name, constructor) {
                        controllerProvider.register(name, constructor);
                        return this;
                    },
                    directive : function(name, constructor) {
                        compileProvider.directive(name, constructor);
                        return this;
                    },
                    filter : function(name, constructor) {
                        filterProvider.register(name, constructor);
                        return this;
                    },
                    factory : function(name, constructor) {
                        // console.log('onDemandLoader.factory called for ' + name);
                        provide.factory(name, constructor);
                        return this;
                    },
                    service : function(name, constructor) {
                        provide.service(name, constructor);
                        return this;
                    },
                    constant : function(name, constructor) {
                        provide.constant(name, constructor);
                        return this;
                    },
                    value : function(name, constructor) {
                        provide.value(name, constructor);
                        return this;
                    },
                    animation: angular.bind(animateProvider, animateProvider.register)
                });
                angular.extend(alt_app, onDemandLoader);

            }]
        );

        // Get the injector for the app
        app.run(['$injector', function ($injector) {
            // $injector must be obtained in .run instead of .config
            run_injector = $injector;
            app_cached_providers.$injector = run_injector;
        }]);

        // Store the app name needed by .bootstrap function.
        app_name = app.name;

        // If there are angular provider recipe queued up, process it
        if (preBootstrapLoaderQueue.length > 0) {
            for (var iq = 0; iq < preBootstrapLoaderQueue.length; iq += 1) {
                var item = preBootstrapLoaderQueue[iq];
                orig_app[item.recipe](item.name, item.constructor);
            }
            preBootstrapLoaderQueue = [];
        }

        // Create a app.register object to keep backward compatibility
        orig_app.register = onDemandLoader;

        // Bootstrap Angular
        orig_angular.element(document).ready(function () {
            orig_angular.bootstrap(elem, [app_name]);
            // Indicate bootstrap completed
            bootstrapped = true;

            // Replace angular.module
            if (enable_ngload) {
                //console.info('Setting alternate angular');
                setAlternateAngular();
            }
        });

        // Return app
        return alt_app;
    };

    // Define provider
    function executeProvider(providerRecipe) {
        return function (name, constructor) {
            if (bootstrapped) {
                onDemandLoader[providerRecipe](name, constructor);
            } else {
                // Queue up the request to be used during .bootstrap
                preBootstrapLoaderQueue.push({
                    'recipe': providerRecipe,
                    'name': name,
                    'constructor': constructor
                });
            }
            return this;
        };
    }

    // .provider
    AngularAMD.prototype.provider = executeProvider('provider');
    // .controller
    AngularAMD.prototype.controller = executeProvider('controller');
    // .directive
    AngularAMD.prototype.directive = executeProvider('directive');
    // .filter
    AngularAMD.prototype.filter = executeProvider('filter');
    // .factory
    AngularAMD.prototype.factory = executeProvider('factory');
    // .service
    AngularAMD.prototype.service = executeProvider('service');
    // .constant
    AngularAMD.prototype.constant = executeProvider('constant');
    // .value
    AngularAMD.prototype.value = executeProvider('value');
    // .animation
    AngularAMD.prototype.animation = executeProvider('animation');

    // Create a new instance and return
    return new AngularAMD();

});
<|endoftext|>


<commit_before>'use strict'

/**
 * Dependencies
 */
const {JSONDocument} = require('json-document')
const KeyChain = require('keychain')
const ProviderSchema = require('./schemas/ProviderSchema')
const AuthenticationRequest = require('./handlers/AuthenticationRequest')
const OpenIDConfigurationRequest = require('./handlers/OpenIDConfigurationRequest')
const DynamicRegistrationRequest = require('./handlers/DynamicRegistrationRequest')
const JWKSetRequest = require('./handlers/JWKSetRequest')
const TokenRequest = require('./handlers/TokenRequest')
const UserInfoRequest = require('./handlers/UserInfoRequest')
const RPInitiatedLogoutRequest = require('./handlers/RPInitiatedLogoutRequest')

/**
 * OpenID Connect Provider
 */
class Provider extends JSONDocument {

  /**
   * constructor
   */
  constructor (data, options) {
    let {issuer} = data

    //assert(issuer, 'OpenID Provider must have an issuer')

    data['authorization_endpoint'] = `${issuer}/authorize`
    data['token_endpoint'] = `${issuer}/token`
    data['userinfo_endpoint'] = `${issuer}/userinfo`
    data['jwks_uri'] = `${issuer}/jwks`
    data['registration_endpoint'] = `${issuer}/register`
    data['check_session_iframe'] = `${issuer}/session`
    data['end_session_endpoint'] = `${issuer}/logout`

    super(data, options)
  }

  /**
   * from
   *
   * @param data {Object} Parsed JSON of a serialized Provider
   * @returns {Promise<Provider>}
   */
  static from (data) {
    let provider = new Provider(data)

    let validation = provider.validate()

    // schema validation
    if (!validation.valid) {
      return Promise.reject(validation)
    }

    return KeyChain.restore(data.keys)
      .then(keychain => {
        provider.keys = keychain

        return provider
      })
  }

  /**
   * initializeKeyChain
   */
  initializeKeyChain () {
    let modulusLength = 2048

    let descriptor = {
      id_token: {
        signing: {
          RS256: { alg: 'RS256', modulusLength },
          RS384: { alg: 'RS384', modulusLength },
          RS512: { alg: 'RS512', modulusLength }
        },
        encryption: {
          // ?
        }
      },
      token: {
        signing: {
          RS256: { alg: 'RS256', modulusLength },
          RS384: { alg: 'RS384', modulusLength },
          RS512: { alg: 'RS512', modulusLength }
        },
        encryption: {}
      },
      userinfo: {
        encryption: {}
      },
      register: {
        signing: {
          RS256: { alg: 'RS256', modulusLength }
        }
      }
    }

    this.keys = new KeyChain(descriptor)
    return this.keys.rotate()
  }

  /**
   * openidConfiguration
   */
  get openidConfiguration () {
    return JSON.stringify(this, Object.keys(ProviderSchema.properties))
  }

  /**
   * jwkSet
   */
  get jwkSet () {
    return this.keys.jwkSet
  }

  /**
   * Schema
   *
   * @returns {JSONSchema}
   */
  static get schema () {
    return ProviderSchema
  }

  /**
   * inject
   */
  inject (properties) {
    Object.keys(properties).forEach(key => {
      let value = properties[key]

      Object.defineProperty(this, key, {
        enumerable: false,
        value
      })
    })
  }

  /**
   * Authorize
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  authorize (req, res) {
    AuthenticationRequest.handle(req, res, this)
  }

  /**
   * Logout
   *
   * Bound to the OP's `end_session_endpoint` uri
   *
   * @param req {HTTPRequest}
   * @param res {HTTPResponse}
   */
  logout (req, res) {
    RPInitiatedLogoutRequest.handle(req, res, this)
  }

  /**
   * Discover
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  discover (req, res) {
    OpenIDConfigurationRequest.handle(req, res, this)
  }

  /**
   * JWKs
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  jwks (req, res) {
    JWKSetRequest.handle(req, res, this)
  }

  /**
   * Register
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  register (req, res) {
    DynamicRegistrationRequest.handle(req, res, this)
  }

  /**
   * Token
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  token (req, res) {
    TokenRequest.handle(req, res, this)
  }

  /**
   * UserInfo
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  userinfo (req, res) {
    UserInfoRequest.handle(req, res, this)
  }
}

/**
 * Export
 */
module.exports = Provider
<commit_msg>feat(Provider): implement provider.importKeyChain()<commit_after>'use strict'

/**
 * Dependencies
 */
const {JSONDocument} = require('json-document')
const KeyChain = require('keychain')
const ProviderSchema = require('./schemas/ProviderSchema')
const AuthenticationRequest = require('./handlers/AuthenticationRequest')
const OpenIDConfigurationRequest = require('./handlers/OpenIDConfigurationRequest')
const DynamicRegistrationRequest = require('./handlers/DynamicRegistrationRequest')
const JWKSetRequest = require('./handlers/JWKSetRequest')
const TokenRequest = require('./handlers/TokenRequest')
const UserInfoRequest = require('./handlers/UserInfoRequest')
const RPInitiatedLogoutRequest = require('./handlers/RPInitiatedLogoutRequest')

/**
 * OpenID Connect Provider
 */
class Provider extends JSONDocument {

  /**
   * constructor
   */
  constructor (data, options) {
    let {issuer} = data

    //assert(issuer, 'OpenID Provider must have an issuer')

    data['authorization_endpoint'] = `${issuer}/authorize`
    data['token_endpoint'] = `${issuer}/token`
    data['userinfo_endpoint'] = `${issuer}/userinfo`
    data['jwks_uri'] = `${issuer}/jwks`
    data['registration_endpoint'] = `${issuer}/register`
    data['check_session_iframe'] = `${issuer}/session`
    data['end_session_endpoint'] = `${issuer}/logout`

    super(data, options)
  }

  /**
   * from
   *
   * @param data {Object} Parsed JSON of a serialized Provider
   * @returns {Promise<Provider>}
   */
  static from (data) {
    let provider = new Provider(data)

    let validation = provider.validate()

    // schema validation
    if (!validation.valid) {
      return Promise.reject(validation)
    }

    return KeyChain.restore(data.keys)
      .then(keychain => {
        provider.keys = keychain

        return provider
      })
  }

  /**
   * initializeKeyChain
   *
   * @param data {Object} Parsed JSON of a serialized provider's .keys property
   * @returns {Promise<Provider>} Resolves to self, chainable
   */
  initializeKeyChain (data) {
    if (!data) {
      return this.generateKeyChain()
    }

    return this.importKeyChain(data)
  }

  /**
   * generateKeyChain
   */
  generateKeyChain () {
    let modulusLength = 2048

    let descriptor = {
      id_token: {
        signing: {
          RS256: { alg: 'RS256', modulusLength },
          RS384: { alg: 'RS384', modulusLength },
          RS512: { alg: 'RS512', modulusLength }
        },
        encryption: {
          // ?
        }
      },
      token: {
        signing: {
          RS256: { alg: 'RS256', modulusLength },
          RS384: { alg: 'RS384', modulusLength },
          RS512: { alg: 'RS512', modulusLength }
        },
        encryption: {}
      },
      userinfo: {
        encryption: {}
      },
      register: {
        signing: {
          RS256: { alg: 'RS256', modulusLength }
        }
      }
    }

    this.keys = new KeyChain(descriptor)
    return this.keys.rotate()
  }

  /**
   * importKeyChain
   *
   * @param data {Object} Parsed JSON of a serialized provider's .keys property
   * @returns {Promise<Provider>} Resolves to self, chainable
   */
  importKeyChain (data) {
    if (!data) {
      return Promise.reject(new Error('Cannot import empty keychain'))
    }

    return KeyChain.restore(data)
      .then(keychain => {
        this.keys = keychain

        return this
      })
  }

  /**
   * openidConfiguration
   */
  get openidConfiguration () {
    return JSON.stringify(this, Object.keys(ProviderSchema.properties))
  }

  /**
   * jwkSet
   */
  get jwkSet () {
    return this.keys.jwkSet
  }

  /**
   * Schema
   *
   * @returns {JSONSchema}
   */
  static get schema () {
    return ProviderSchema
  }

  /**
   * inject
   */
  inject (properties) {
    Object.keys(properties).forEach(key => {
      let value = properties[key]

      Object.defineProperty(this, key, {
        enumerable: false,
        value
      })
    })
  }

  /**
   * Authorize
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  authorize (req, res) {
    AuthenticationRequest.handle(req, res, this)
  }

  /**
   * Logout
   *
   * Bound to the OP's `end_session_endpoint` uri
   *
   * @param req {HTTPRequest}
   * @param res {HTTPResponse}
   */
  logout (req, res) {
    RPInitiatedLogoutRequest.handle(req, res, this)
  }

  /**
   * Discover
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  discover (req, res) {
    OpenIDConfigurationRequest.handle(req, res, this)
  }

  /**
   * JWKs
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  jwks (req, res) {
    JWKSetRequest.handle(req, res, this)
  }

  /**
   * Register
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  register (req, res) {
    DynamicRegistrationRequest.handle(req, res, this)
  }

  /**
   * Token
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  token (req, res) {
    TokenRequest.handle(req, res, this)
  }

  /**
   * UserInfo
   *
   * @param {HTTPRequest} req
   * @param {HTTPResponse} res
   */
  userinfo (req, res) {
    UserInfoRequest.handle(req, res, this)
  }
}

/**
 * Export
 */
module.exports = Provider
<|endoftext|>