Skip to content

Instantly share code, notes, and snippets.

@iotashan
Created April 22, 2015 01:42

Revisions

  1. iotashan created this gist Apr 22, 2015.
    263 changes: 263 additions & 0 deletions LinkedInAuth.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,263 @@
    /*
    * LinkedIn account authentfication library / module
    * by Miroslav Magda, blog.ejci.net,
    *
    *
    * Copyright 2012 Miroslav Magda
    *
    * All code is open source and dual licensed under GPL and MIT. Check the individual licenses for more information.
    */

    /*
    * LinkedIn authentification for Titanium
    * based on: https://github.com/ejci/Google-Auth-for-Titanium
    * Check also https://code.google.com/apis/console/
    */

    var LinkedInAuth = function(o) {
    var _version = '0.3.2';
    o = (o) ? o : {};
    var _opt = {
    clientId : (o.clientId) ? o.clientId : null,
    clientSecret : (o.clientSecret) ? o.clientSecret : null,
    propertyName : (o.propertyName) ? o.propertyName : 'linkedinToken',
    url : 'https://www.linkedin.com/uas/oauth2/authorization',
    scope : (o.scope) ? o.scope : ['r_basicprofile'],
    closeTitle : (o.closeTitle) ? o.closeTitle : 'Close',
    errorText : (o.errorText) ? o.errorText : 'Can not authorize user!',
    quiet : ( typeof (o.quiet) === 'undefined') ? true : o.quiet,
    };
    var log = function() {
    };
    log.error = function(t) {
    if (!_opt.quiet) {
    Ti.API.error('' + t);
    }
    };
    log.info = function(t) {
    if (!_opt.quiet) {
    Ti.API.info(t);
    }
    };
    log.debug = function(t) {
    if (!_opt.quiet) {
    Ti.API.debug('' + t);
    }
    };
    log.trace = function(t) {
    if (!_opt.quiet) {
    Ti.API.trace('' + t);
    }
    };
    //UTILS

    log.info('-------------------------------------');
    log.info('| LinkedIn Account Authentification |');
    log.info('| Titanium Module (v.:' + _version + ') |');
    log.info('| by Miroslav Magda |');
    log.info('-------------------------------------');

    var win;

    var _prop = {};
    _prop.accessToken = null;
    _prop.refreshToken = null;
    _prop.tokenType = null;
    _prop.expiresIn = 0;

    var prop = {};
    prop = getProps();

    if (prop.expiresIn >= (new Date()).getTime()) {
    log.info('LinkedInAuth: Access code valid');
    _prop = prop;
    }/*else {
    log.info('LinkedInAuth: Access code not valid. Refreshing...');
    _prop = prop;
    refreshToken();
    }*/
    function reset() {
    Ti.App.Properties.removeProperty(_opt.propertyName + '.accessToken');
    Ti.App.Properties.removeProperty(_opt.propertyName + '.refreshToken');
    Ti.App.Properties.removeProperty(_opt.propertyName + '.tokenType');
    Ti.App.Properties.removeProperty(_opt.propertyName + '.expiresIn');
    }

    function getProps() {
    var p = {};
    p.accessToken = Ti.App.Properties.getString(_opt.propertyName + '.accessToken');
    p.refreshToken = Ti.App.Properties.getString(_opt.propertyName + '.refreshToken');
    p.tokenType = Ti.App.Properties.getString(_opt.propertyName + '.tokenType');
    p.expiresIn = Ti.App.Properties.getString(_opt.propertyName + '.expiresIn');
    return p;
    }

    function authorize(cb) {
    cb = (cb) ? cb : function() {
    };
    var url = prepareUrl();

    Ti.Platform.openURL(url);
    }

    /**
    * Refresh token
    */
    function refreshToken(cbSuccess, cbError) {
    log.info('LinkedInAuth: Access code not valid. Refreshing...');
    cbSuccess = (cbSuccess) ? cbSuccess : function() {
    };
    cbError = (cbError) ? cbError : function() {
    };
    var xhr = Ti.Network.createHTTPClient({
    // function called when the response data is available
    onload : function(e) {
    //log.info("Received text: " + this.responseText);
    var resp = JSON.parse(this.responseText);
    resp.expires_in = parseFloat(resp.expires_in, 10) * 1000 + (new Date()).getTime();
    Ti.App.Properties.setString(_opt.propertyName + '.accessToken', resp.access_token);
    Ti.App.Properties.setString(_opt.propertyName + '.tokenType', resp.token_type);
    Ti.App.Properties.setString(_opt.propertyName + '.expiresIn', resp.expires_in);
    _prop.accessToken = resp.access_token;
    _prop.tokenType = resp.token_type;
    _prop.expiresIn = resp.expires_in;
    log.debug(_prop);
    cbSuccess();
    },
    // function called when an error occurs, including a timeout
    onerror : function(e) {
    log.info(e.error);
    log.info(e.responseText);
    cbError();
    //ERROR
    Titanium.UI.createAlertDialog({
    title : 'Error',
    message : _opt.errorText
    });

    //authorize();

    },
    timeout : 5000 /* in milliseconds */
    });
    // Prepare the connection.
    xhr.open("POST", _opt.url);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    var d = {
    client_id : _opt.clientId,
    client_secret : _opt.clientSecret,
    refresh_token : _prop.refreshToken,
    grant_type : 'refresh_token'
    };
    // Send the request.
    xhr.send(d);
    }

    /**
    * Get TOKEN
    */
    function getToken(code, cb) {
    cb = (cb) ? cb : function() {
    };
    var xhr = Ti.Network.createHTTPClient({
    // function called when the response data is available
    onload : function(e) {
    //log.info("Received text: " + this.responseText);
    var resp = JSON.parse(this.responseText);
    log.info(resp.expires_in);
    resp.expires_in = parseFloat(resp.expires_in, 10) * 1000 + (new Date()).getTime();
    log.info(resp.expires_in);
    Ti.App.Properties.setString(_opt.propertyName + '.accessToken', resp.access_token);
    Ti.App.Properties.setString(_opt.propertyName + '.refreshToken', resp.refresh_token);
    Ti.App.Properties.setString(_opt.propertyName + '.tokenType', resp.token_type);
    Ti.App.Properties.setString(_opt.propertyName + '.expiresIn', resp.expires_in);
    _prop.accessToken = resp.access_token;
    _prop.refreshToken = resp.refresh_token;
    _prop.tokenType = resp.token_type;
    _prop.expiresIn = resp.expires_in;
    log.debug(_prop);
    //alert('success');
    //callback
    cb();
    },
    // function called when an error occurs, including a timeout
    onerror : function(e) {
    //log.info(e.error);
    //log.info(e.responseText);
    //TODO: show some error message
    Titanium.UI.createAlertDialog({
    title : 'Error',
    message : _opt.errorText
    });
    },
    timeout : 5000 /* in milliseconds */
    });
    // Prepare the connection.
    xhr.open("POST", 'https://www.linkedin.com/uas/oauth2/accessToken');
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    var d = {
    code : code,
    client_id : _opt.clientId,
    client_secret : _opt.clientSecret,
    redirect_uri : 'http://www.yoursite.com/mobileredirect/', // TODO: you need a public web URL that will redirect to your app's URL pattern, like myapp://
    grant_type : 'authorization_code'
    };
    // Send the request.
    xhr.send(d);
    }

    /**
    * Prepare url from options
    */
    function prepareUrl() {
    //encodeURIComponent(_opt.scope.join('+'))
    var scope = [];
    for (var i = 0; i < _opt.scope.length; i++) {
    scope[i] = encodeURIComponent(_opt.scope[i]);
    }
    // var url = _opt.url + '?' + 'approval_prompt=force&scope=' + scope.join('+') + '&' + 'redirect_uri=urn:ietf:wg:oauth:2.0:oob' + '&' + 'response_type=code' + '&' + 'client_id=' + _opt.clientId + '&' + 'btmpl=mobile' + '';
    var url = _opt.url + '?' + 'approval_prompt=force&scope=' + scope.join('+') + '&' + 'redirect_uri=http%3A%2F%yoursite.com%mobileredirect%2F' + '&' + 'response_type=code' + '&' + 'client_id=' + _opt.clientId + '&' + 'btmpl=mobile' + '&' + 'state=iuq873iyhjks' + ''; // TODO: you need a public web URL that will redirect to your app's URL pattern, like myapp://
    if (_opt.loginHint) {
    url = url + '&' + 'login_hint=' + encodeURIComponent(_opt.loginHint);
    }
    log.debug(url);
    return url;
    }

    function isAuthorized(cbSuccess, cbError) {
    cbSuccess = (cbSuccess) ? cbSuccess : function() {
    };
    cbError = (cbError) ? cbError : function() {
    };
    _prop = getProps();
    log.debug('Properties: ' + JSON.stringify(_prop));
    if (_prop.accessToken != null && _prop.accessToken != '') {
    if (_prop.expiresIn < (new Date()).getTime()) {
    refreshToken(cbSuccess, cbError);
    } else {
    cbSuccess();
    }
    return true;
    } else {
    cbError();
    }

    return false;
    }

    function getAccessToken() {
    return _prop.accessToken;
    }

    return {
    isAuthorized : isAuthorized,
    processCode : getToken,
    getAccessToken : getAccessToken,
    refreshToken : refreshToken,
    authorize : authorize,
    version : _version,
    reset : reset,
    };
    };

    module.exports = LinkedInAuth;