From afab879f936a516aab130730d036e553c6319584 Mon Sep 17 00:00:00 2001 From: German Lena Date: Thu, 1 Dec 2016 10:54:23 -0300 Subject: [PATCH 1/3] Upgrate to auth0.js v8 Authorization flows support enabling oidcComformant mode First class support for nonce, state and audience --- bower.json | 2 +- package.json | 8 +- scripts/ci.sh | 6 +- src/connection/database/actions.js | 12 +- src/core/actions.js | 42 +++--- src/core/index.js | 20 ++- src/core/remote_data.js | 32 ++--- src/core/web_api.js | 207 ++++------------------------- src/core/web_api/helper.js | 116 ++++++++++++++++ src/core/web_api/legacy_api.js | 101 ++++++++++++++ src/core/web_api/p2_api.js | 98 ++++++++++++++ src/index.js | 4 - src/utils/cdn_utils.js | 2 +- support/index.html | 13 +- 14 files changed, 420 insertions(+), 243 deletions(-) create mode 100644 src/core/web_api/helper.js create mode 100644 src/core/web_api/legacy_api.js create mode 100644 src/core/web_api/p2_api.js diff --git a/bower.json b/bower.json index 8a2f30dd2..142ee8fa9 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "auth0-lock", - "version": "10.8.1", + "version": "10.8.0-beta.1", "main": "build/lock.js", "ignore": [ "lib-cov", diff --git a/package.json b/package.json index 4420cd3e8..9162a3ad9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "auth0-lock", - "version": "10.8.1", + "version": "10.8.0-beta.5", "description": "Auth0 Lock", "author": "Auth0 (http://auth0.com)", "license": "MIT", @@ -79,7 +79,7 @@ "zuul-ngrok": "gnandretta/zuul-ngrok#upgrade-ngrok" }, "dependencies": { - "auth0-js": "7.6.1", + "auth0-js": "8.0.0", "blueimp-md5": "2.3.1", "fbjs": "^0.3.1", "immutable": "^3.7.3", @@ -96,6 +96,8 @@ "cdn": "https://cdn.auth0.com", "mainBundleFile": "lock.min.js", "bucket": "assets.us.auth0.com", - "localPath": "build" + "localPath": "build", + "majorAndMinor": false, + "snapshot": false } } diff --git a/scripts/ci.sh b/scripts/ci.sh index ba6521663..d1d32651d 100755 --- a/scripts/ci.sh +++ b/scripts/ci.sh @@ -3,7 +3,7 @@ npm install MATCHER=${2:-"*"} -NPM_TAG=${3:-"latest"} +NPM_TAG=${3:-"beta"} NPM_NAME=$(node scripts/utils/attribute.js name) VERSION=$(node scripts/utils/attribute.js version) @@ -37,7 +37,7 @@ success() cdn_release() { - npm run publish:cdn + npm run publish:cdn -- --full-version-only new_line success "$NPM_NAME ($1) uploaded to cdn" } @@ -99,7 +99,7 @@ npm run dist build # Release git checkout -b dist -bower_release +#bower_release new_line npm_release "$VERSION" new_line diff --git a/src/connection/database/actions.js b/src/connection/database/actions.js index 6843037c6..352788c27 100644 --- a/src/connection/database/actions.js +++ b/src/connection/database/actions.js @@ -79,13 +79,13 @@ export function signUp(id) { if (error) { setTimeout(() => signUpError(id, error), 250); } else { - signUpSuccess(id); + signUpSuccess(id, ...args); } }); }); } -function signUpSuccess(id) { +function signUpSuccess(id, result, popupHandler) { const lock = read(getEntity, "lock", id); if (shouldAutoLogin(lock)) { @@ -98,6 +98,10 @@ function signUpSuccess(id) { password: c.password(lock) }; + if (!!popupHandler) { + options.popupHandler = popupHandler; + } + return webApi.logIn( id, options, @@ -116,10 +120,10 @@ function signUpSuccess(id) { if (!autoclose) { swap(updateEntity, "lock", id, lock => l.setSubmitting(lock, false).set("signedUp", true)); + } else { closeLock(id, false); } - } function signUpError(id, error) { @@ -132,7 +136,7 @@ function signUpError(id, error) { }; const errorKey = (error.code === "invalid_password" - && invalidPasswordKeys[error.details.name]) + && invalidPasswordKeys[error.description]) || error.code; const errorMessage = i18n.str(m, ["error", "signUp", errorKey]) diff --git a/src/core/actions.js b/src/core/actions.js index a3df88591..563fb457d 100644 --- a/src/core/actions.js +++ b/src/core/actions.js @@ -30,40 +30,34 @@ export function handleAuthCallback() { const hash = global.location.hash; const ms = read(getCollection, "lock"); - const parsed = ms.filter(m => l.auth.redirect(m) && parseHash(m, hash)); const keepHash = ms.filter(m => !l.hashCleanup(m)).size > 0; - if (parsed.size > 0 && !keepHash) { - global.location.hash = ""; - } + ms.forEach(m => { + l.auth.redirect(m) && parseHash(m, hash, (result) => { + if (result && !keepHash) { + global.location.hash = ""; + } + }) + }); } -function parseHash(m, hash) { - const parsedHash = webApi.parseHash(l.id(m), hash); - l.emitHashParsedEvent(m, parsedHash); - - let error, result; - - if (parsedHash) { - if (parsedHash.error) { - error = parsedHash; - } else if (!parsedHash.hasOwnProperty("error")) { - // NOTE: if the url hash contains the string "error" - // `parsedHash` will be the following object: - // {error: undefined, error_description: undefined} - // That is why we make the additional check for the error - // property to ensure we actually have a result. - result = parsedHash; +function parseHash(m, hash, cb) { + webApi.parseHash(l.id(m), hash, function(error, parsedHash) { + + if (error) { + l.emitHashParsedEvent(m, error); + } else { + l.emitHashParsedEvent(m, parsedHash); } if (error) { l.emitAuthorizationErrorEvent(m, error); - } else if (result) { - l.emitAuthenticatedEvent(m, result); + } else if (parsedHash) { + l.emitAuthenticatedEvent(m, parsedHash); } - } - return !!(error || result); + cb(!!(error || parsedHash)) + }); } export function openLock(id, opts) { diff --git a/src/core/index.js b/src/core/index.js index 079779e27..bef2eebdf 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -34,6 +34,7 @@ export function setup(id, clientID, domain, options, hookRunner, emitEventFn) { emitEventFn: emitEventFn, hookRunner: hookRunner, useTenantInfo: options.__useTenantInfo || false, + oidcConformant: options.oidcConformant || false, hashCleanup: options.hashCleanup === false ? false : true, allowedConnections: Immutable.fromJS(options.allowedConnections || []), ui: extractUIOptions(id, options), @@ -69,6 +70,10 @@ export function useTenantInfo(m) { return get(m, "useTenantInfo"); } +export function oidcConformant(m) { + return get(m, "oidcConformant"); +} + export function languageBaseUrl(m) { return get(m, "languageBaseUrl"); } @@ -201,20 +206,26 @@ export const auth = { function extractAuthOptions(options) { let { + audience, connectionScopes, params, redirect, redirectUrl, responseMode, responseType, - sso + sso, + state, + nonce } = options.auth || {}; + audience = typeof audience === "string" ? audience : undefined; connectionScopes = typeof connectionScopes === "object" ? connectionScopes : {}; params = typeof params === "object" ? params : {}; - redirectUrl = typeof redirectUrl === "string" && redirectUrl ? redirectUrl : undefined; + redirectUrl = typeof redirectUrl === "string" && redirectUrl ? redirectUrl : window.location.href; redirect = typeof redirect === "boolean" ? redirect : true; responseMode = typeof responseMode === "string" ? responseMode : undefined; + state = typeof state === "string" ? state : undefined; + nonce = typeof nonce === "string" ? nonce : undefined; responseType = typeof responseType === "string" ? responseType : redirectUrl ? "code" : "token"; sso = typeof sso === "boolean" ? sso : true; @@ -224,13 +235,16 @@ function extractAuthOptions(options) { } return Immutable.fromJS({ + audience, connectionScopes, params, redirect, redirectUrl, responseMode, responseType, - sso + sso, + state, + nonce }); } diff --git a/src/core/remote_data.js b/src/core/remote_data.js index cf4c10acc..4ef907000 100644 --- a/src/core/remote_data.js +++ b/src/core/remote_data.js @@ -20,23 +20,25 @@ export function syncRemoteData(m) { }); } - m = sync(m, "sso", { - conditionFn: l.auth.sso, - waitFn: m => isSuccess(m, "client"), - syncFn: (m, cb) => fetchSSOData(l.id(m), isADEnabled(m), cb), - successFn: (m, result) => m.mergeIn(["sso"], Immutable.fromJS(result)), - errorFn: (m, error) => { - // location.origin is not supported in all browsers - let origin = location.protocol + "//" + location.hostname; - if (location.port) { - origin += ":" + location.port; - } + if (!l.oidcConformant(m)) { + m = sync(m, "sso", { + conditionFn: l.auth.sso, + waitFn: m => isSuccess(m, "client"), + syncFn: (m, cb) => fetchSSOData(l.id(m), isADEnabled(m), cb), + successFn: (m, result) => m.mergeIn(["sso"], Immutable.fromJS(result)), + errorFn: (m, error) => { + // location.origin is not supported in all browsers + let origin = location.protocol + "//" + location.hostname; + if (location.port) { + origin += ":" + location.port; + } - const appSettingsUrl = `https://manage.auth0.com/#/applications/${l.clientID(m)}/settings`; + const appSettingsUrl = `https://manage.auth0.com/#/applications/${l.clientID(m)}/settings`; - l.warn(m, `There was an error fetching the SSO data. This could simply mean that there was a problem with the network. But, if a "Origin" error has been logged before this warning, please add "${origin}" to the "Allowed Origins (CORS)" list in the Auth0 dashboard: ${appSettingsUrl}`); - } - }); + l.warn(m, `There was an error fetching the SSO data. This could simply mean that there was a problem with the network. But, if a "Origin" error has been logged before this warning, please add "${origin}" to the "Allowed Origins (CORS)" list in the Auth0 dashboard: ${appSettingsUrl}`); + } + }); + } return m; } \ No newline at end of file diff --git a/src/core/web_api.js b/src/core/web_api.js index b813c5054..606440fa2 100644 --- a/src/core/web_api.js +++ b/src/core/web_api.js @@ -1,39 +1,31 @@ -import Auth0 from 'auth0-js'; +import auth0 from 'auth0-js'; +import Auth0LegacyAPIClient from './web_api/legacy_api' +import Auth0APIClient from './web_api/p2_api' class Auth0WebAPI { constructor() { this.clients = {}; - this.authOpts = {}; - this.authParams = {}; } setupClient(lockID, clientID, domain, opts) { - this.clients[lockID] = new Auth0({ - clientID: clientID, - domain: domain, - sendSDKClientInfo: true, - forceJSONP: false, - callbackURL: opts.redirectUrl, - responseMode: opts.responseMode, - responseType: opts.responseType, - __tenant: opts.overrides && opts.overrides.__tenant, - __token_issuer: opts.overrides && opts.overrides.__token_issuer - }); - this.authOpts[lockID] = { - popup: !opts.redirect, - popupOptions: opts.popupOptions, - sso: opts.sso - }; + const hostedLoginPage = window.location.host === domain; + // when it is used on on the hosted login page, it shouldn't use popup mode + opts.popup = hostedLoginPage ? opts.popup : false; + + opts.oidcConformant = opts.oidcConformant || false; + + // when it is used on on the hosted login page, it should use the legacy mode + // (usernamepassword/login) in order to continue the transaction after authentication + if (hostedLoginPage || !opts.oidcConformant) { + this.clients[lockID] = new Auth0LegacyAPIClient(clientID, domain, opts); + } else { + this.clients[lockID] = new Auth0APIClient(clientID, domain, opts); + } } logIn(lockID, options, authParams, cb) { - // TODO: for passwordless only, try to clean in auth0.js - // client._shouldRedirect = redirect || responseType === "code" || !!redirectUrl; - const authOpts = this.authOpts[lockID]; - const f = loginCallback(!authOpts.popup, cb); - const client = this.clients[lockID]; - client.login({...options, ...authOpts, ...authParams}, f); + this.clients[lockID].logIn(options, authParams, cb); } signOut(lockID, query) { @@ -41,53 +33,19 @@ class Auth0WebAPI { } signUp(lockID, options, cb) { - const client = this.clients[lockID]; - const { popup, sso } = this.authOpts[lockID]; - const { autoLogin } = options; - delete options.autoLogin; - - // TODO: investigate why can't we just delegate to auth0.js the - // automatic login (error handling maybe?). - - // When needed, open popup for sso login immediately, otherwise it - // may be blocked by the browser. - let win; - if (autoLogin && popup && sso) { - win = client._buildPopupWindow({}); - } - - // Never allow automatic login and disable popup (since it is only - // needed when auth0.js handles the automatic login). - options.auto_login = false; - options.popup = false; - - // Also, wrap callback in a function that closes the popup. - const f = (error, ...args) => { - if (error && win) { - win.kill(); - } - - cb(error, ...args); - }; - - client.signup(options, f); + this.clients[lockID].signUp(options, cb); } resetPassword(lockID, options, cb) { - this.clients[lockID].changePassword(options, cb); + this.clients[lockID].resetPassword(options, cb); } startPasswordless(lockID, options, cb) { - const client = this.clients[lockID]; - client.startPasswordless(options, err => cb(normalizeError(err))); - } - - parseHash(lockID, hash = '') { - return this.clients[lockID].parseHash(decodeURIComponent(hash)); + this.clients[lockID].startPasswordless(options, cb); } - getProfile(lockID, token, callback) { - return this.clients[lockID].getProfile(token, callback); + parseHash(lockID, hash = '', cb) { + return this.clients[lockID].parseHash(decodeURIComponent(hash), cb); } getUserInfo(lockID, token, callback) { @@ -99,127 +57,8 @@ class Auth0WebAPI { } getUserCountry(lockID, cb) { - return this.clients[lockID].getUserCountry(cb); + return this.clients[lockID].getUserCountry((err, data) => cb(err, data && data.countryCode)); } } export default new Auth0WebAPI(); - -function normalizeError(error) { - if (!error) { - return error; - } - - // TODO: clean this mess, the first checks are for social/popup, - // then we have some stuff for passwordless and the latter is for - // db. - - // TODO: the following checks were copied from https://github.com/auth0/lock/blob/0a5abf1957c9bb746b0710b274d0feed9b399958/index.js#L1263-L1288 - // Some of the checks are missing because I couldn't reproduce them and I'm - // affraid they'll break existent functionality if add them. - // We need a better errror handling story in auth0.js. - - if (error.status === "User closed the popup window") { - // { - // status: "User closed the popup window", - // name: undefined, - // code: undefined, - // details: { - // description: "server error", - // code: undefined - // } - // } - return { - code: "lock.popup_closed", - error: "lock.popup_closed", - description: "Popup window closed." - }; - } - - if (error.code === "unauthorized") { - - // Custom rule error - // - // { - // "code": "unauthorized", - // "details": { - // "code": "unauthorized", - // "error_description": "user is blocked", - // "error": "unauthorized" - // }, - // "name": "unauthorized", - // "status": 401 - // } - - // Default "user is blocked" rule error - // - // { - // "code": "unauthorized", - // "details": { - // "code": "unauthorized", - // "error_description": "user is blocked", - // "error": "unauthorized" - // }, - // "name": "unauthorized", - // "status": 401 - // } - - // Social cancel permissions. - // - // { - // code: "unauthorized", - // details: { - // code: "unauthorized" - // error: "unauthorized" - // error_description: "access_denied" - // }, - // name: "unauthorized" - // status: 401 - // } - - // Social cancel permissions or unknown error - if (!error.details - || !error.details.error_description - || error.details.error_description === "access_denied") { - - return { - code: "lock.unauthorized", - error: "lock.unauthorized", - description: (error.details && error.details.error_description) || "Permissions were not granted." - } - } - - // Special case for custom rule error - if (error.details.error_description === "user is blocked") { - return { - code: "blocked_user", - error: "blocked_user", - description: error.details.error_description - }; - } - - // Custom Rule error - return { - code: "rule_error", - error: "rule_error", - description: error.details.error_description - }; - - } - - const result = { - error: error.details ? error.details.error : (error.code || error.statusCode || error.error), - description: error.details ? error.details.error_description : (error.error_description || error.description || error.error) - } - - // result is used for passwordless and error for database. - return result.error === undefined && result.description === undefined - ? error - : result; -} - -function loginCallback(redirect, cb) { - return redirect - ? error => cb(normalizeError(error)) - : (error, result) => cb(normalizeError(error), result); -} diff --git a/src/core/web_api/helper.js b/src/core/web_api/helper.js new file mode 100644 index 000000000..1a18c93da --- /dev/null +++ b/src/core/web_api/helper.js @@ -0,0 +1,116 @@ +export function normalizeError(error) { + if (!error) { + return error; + } + + // TODO: clean this mess, the first checks are for social/popup, + // then we have some stuff for passwordless and the latter is for + // db. + + // TODO: the following checks were copied from https://github.com/auth0/lock/blob/0a5abf1957c9bb746b0710b274d0feed9b399958/index.js#L1263-L1288 + // Some of the checks are missing because I couldn't reproduce them and I'm + // affraid they'll break existent functionality if add them. + // We need a better errror handling story in auth0.js. + + if (error.status === "User closed the popup window") { + // { + // status: "User closed the popup window", + // name: undefined, + // code: undefined, + // details: { + // description: "server error", + // code: undefined + // } + // } + return { + code: "lock.popup_closed", + error: "lock.popup_closed", + description: "Popup window closed." + }; + } + + if (error.code === "unauthorized") { + + // Custom rule error + // + // { + // "code": "unauthorized", + // "details": { + // "code": "unauthorized", + // "error_description": "user is blocked", + // "error": "unauthorized" + // }, + // "name": "unauthorized", + // "status": 401 + // } + + // Default "user is blocked" rule error + // + // { + // "code": "unauthorized", + // "details": { + // "code": "unauthorized", + // "error_description": "user is blocked", + // "error": "unauthorized" + // }, + // "name": "unauthorized", + // "status": 401 + // } + + // Social cancel permissions. + // + // { + // code: "unauthorized", + // details: { + // code: "unauthorized" + // error: "unauthorized" + // error_description: "access_denied" + // }, + // name: "unauthorized" + // status: 401 + // } + + // Social cancel permissions or unknown error + if (!error.description || error.description === "access_denied") { + + return { + code: "lock.unauthorized", + error: "lock.unauthorized", + description: error.description || "Permissions were not granted." + } + } + + // Special case for custom rule error + if (error.description === "user is blocked") { + return { + code: "blocked_user", + error: "blocked_user", + description: error.description + }; + } + + // Custom Rule error + return { + code: "rule_error", + error: "rule_error", + description: error.description + }; + + } + + const result = { + error: error.code ? error.code : (error.statusCode || error.error), + description: error.description || error.code + } + + // result is used for passwordless and error for database. + return result.error === undefined && result.description === undefined + ? error + : result; +} + +export function loginCallback(redirect, cb) { + return redirect + ? error => cb(normalizeError(error)) + : (error, result) => cb(normalizeError(error), result); +} diff --git a/src/core/web_api/legacy_api.js b/src/core/web_api/legacy_api.js new file mode 100644 index 000000000..6e3628d29 --- /dev/null +++ b/src/core/web_api/legacy_api.js @@ -0,0 +1,101 @@ +import auth0 from 'auth0-js'; +import {normalizeError, loginCallback} from './helper'; + +class Auth0LegacyAPIClient { + constructor(clientID, domain, opts) { + this.client = null; + this.authOpt = null; + + const default_telemetry = { + name: 'lock.js', + version: __VERSION__, + lib_version: auth0.version + }; + + this.client = new auth0.WebAuth({ + clientID: clientID, + domain: domain, + redirectUri: opts.redirectUrl, + responseMode: opts.responseMode, + responseType: opts.responseType, + _sendTelemetry: opts._sendTelemetry === false ? false : true, + _telemetryInfo: opts._telemetryInfo || default_telemetry, + __tenant: opts.overrides && opts.overrides.__tenant, + __token_issuer: opts.overrides && opts.overrides.__token_issuer + }); + + this.authOpt = { + popup: !opts.redirect, + popupOptions: opts.popupOptions, + sso: opts.sso, + nonce: opts.nonce, + state: opts.state + }; + } + + logIn(options, authParams, cb) { + // TODO: for passwordless only, try to clean in auth0.js + // client._shouldRedirect = redirect || responseType === "code" || !!redirectUrl; + const f = loginCallback(!this.authOpt.popup, cb); + const auth0Client = this.client; + + if (!options.username && !options.email) { + if (this.authOpt.popup) { + auth0Client.popup.authorize({...options, ...this.authOpt, ...authParams}, f) + } else { + auth0Client.authorize({...options, ...this.authOpt, ...authParams}, f) + } + } else if (!this.authOpt.sso && this.authOpt.popup) { + auth0Client.client.loginWithResourceOwner({...options, ...this.authOpt, ...authParams}, f) + } else if (this.authOpt.popup) { + auth0Client.popup.loginWithCredentials({...options, ...this.authOpt, ...authParams}, f) + } else { + auth0Client.redirect.loginWithCredentials({...options, ...this.authOpt, ...authParams}, f); + } + } + + signOut(query) { + this.client.logout(query); + } + + signUp(options, cb) { + const { popup, sso } = this.authOpt; + const { autoLogin } = options; + + delete options.autoLogin; + + const popupHandler = (autoLogin && popup) ? this.client.popup.preload() : null; + + this.client.signup(options, (err, result) => cb(err, result, popupHandler) ); + } + + resetPassword(options, cb) { + this.client.changePassword(options, cb); + } + + startPasswordless(options, cb) { + this.client.startPasswordless(options, err => cb(normalizeError(err))); + } + + parseHash(hash = '', cb) { + return this.client.parseHash({ + hash: decodeURIComponent(hash), + nonce: this.authOpt.nonce, + state: this.authOpt.state + }, cb); + } + + getUserInfo(token, callback) { + return this.client.client.userInfo(token, callback); + } + + getSSOData(...args) { + return this.client.client.getSSOData(...args); + } + + getUserCountry(cb) { + return this.client.getUserCountry(cb); + } +} + +export default Auth0LegacyAPIClient; \ No newline at end of file diff --git a/src/core/web_api/p2_api.js b/src/core/web_api/p2_api.js new file mode 100644 index 000000000..038b4b83c --- /dev/null +++ b/src/core/web_api/p2_api.js @@ -0,0 +1,98 @@ +import auth0 from 'auth0-js'; +import {normalizeError, loginCallback} from './helper'; + +class Auth0APIClient { + constructor(clientID, domain, opts) { + this.client = null; + this.authOpt = null; + + const default_telemetry = { + name: 'lock.js', + version: __VERSION__, + lib_version: auth0.version + }; + + this.client = new auth0.WebAuth({ + clientID: clientID, + domain: domain, + audience: opts.audience, + redirectUri: opts.redirectUrl, + responseMode: opts.responseMode, + responseType: opts.responseType, + _sendTelemetry: opts._sendTelemetry === false ? false : true, + _telemetryInfo: opts._telemetryInfo || default_telemetry, + __tenant: opts.overrides && opts.overrides.__tenant, + __token_issuer: opts.overrides && opts.overrides.__token_issuer + }); + + this.authOpt = { + popup: !opts.redirect, + popupOptions: opts.popupOptions, + sso: opts.sso, + nonce: opts.nonce, + state: opts.state + }; + } + + logIn(options, authParams, cb) { + // TODO: for passwordless only, try to clean in auth0.js + // client._shouldRedirect = redirect || responseType === "code" || !!redirectUrl; + const f = loginCallback(false, cb); + + if (!options.username && !options.email) { + if (this.authOpt.popup) { + this.client.popup.authorize({...options, ...this.authOpt, ...authParams}, f) + } else { + this.client.authorize({...options, ...this.authOpt, ...authParams}, f) + } + } else { + options.realm = options.connection; + this.client.client.login({...options, ...this.authOpt, ...authParams}, f); + } + } + + signOut(query) { + this.client.logout(query); + } + + signUp(options, cb) { + const { popup, sso } = this.authOpt; + const { autoLogin } = options; + + delete options.autoLogin; + + const popupHandler = (autoLogin && popup) ? this.client.popup.preload() : null; + + this.client.signup(options, (err, result) => cb(err, result, popupHandler) ); + } + + resetPassword(options, cb) { + this.client.changePassword(options, cb); + } + + startPasswordless(options, cb) { + this.client.startPasswordless(options, err => cb(normalizeError(err))); + } + + parseHash(hash = '', cb) { + return this.client.parseHash({ + hash: decodeURIComponent(hash), + nonce: this.authOpt.nonce, + state: this.authOpt.state + }, cb); + } + + getUserInfo(token, callback) { + return this.client.client.userInfo(token, callback); + } + + getSSOData(...args) { + return this.client.client.getSSOData(...args); + } + + getUserCountry(cb) { + return this.client.getUserCountry(cb); + } +} + +export default Auth0APIClient; diff --git a/src/index.js b/src/index.js index 1ba7d4448..df93a875a 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,3 @@ -import Auth0 from 'auth0-js'; import Core from './core'; import classic from './engine/classic'; import css from '../css/index.styl'; @@ -35,9 +34,6 @@ export default class Auth0Lock extends Core { // telemetry Auth0Lock.version = __VERSION__; Auth0Lock.css = css; -Auth0.clientInfo.lib_version = Auth0.clientInfo.version; -Auth0.clientInfo.name = "lock.js"; -Auth0.clientInfo.version = Auth0Lock.version; // TODO: should we have different telemetry for classic/passwordless? // TODO: should we set telemetry info before each request? diff --git a/src/utils/cdn_utils.js b/src/utils/cdn_utils.js index 5034de41a..90a0e74f4 100644 --- a/src/utils/cdn_utils.js +++ b/src/utils/cdn_utils.js @@ -1,7 +1,7 @@ import Auth0 from 'auth0-js'; if (!global.Auth0) { - global.Auth0 = Auth0; + global.Auth0 = {}; } const cbs = {}; diff --git a/support/index.html b/support/index.html index 4228a0a43..068da7f81 100644 --- a/support/index.html +++ b/support/index.html @@ -16,18 +16,29 @@ const cid = "ixeOHFhD7NSPxEQK6CFcswjUsa5YkcXS"; const domain = "auth0-tests-lock.auth0.com"; const options = { - rememberLastLogin: true + auth: { + responseType: 'token', + redirect: false + }, + oidcConformant: false }; const lock = new Auth0Lock(cid, domain, options); lock.on("authenticated", function(authResult) { console.log(authResult); + + if (!authResult.accessToken) return; + lock.getUserInfo(authResult.accessToken, function(error, profile) { console.log(error, profile); }); }); + lock.on("authorization_error", function(error) { + console.log('authorization_error', error); + }); + lock.show({ languageDictionary: { title: "sarlanga" From 2be7966aee0d4652759e41acccb0da79686e9d4c Mon Sep 17 00:00:00 2001 From: German Lena Date: Wed, 4 Jan 2017 15:44:13 -0300 Subject: [PATCH 2/3] bump auth0.js dependency --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 9162a3ad9..b3f30c7ca 100644 --- a/package.json +++ b/package.json @@ -79,7 +79,7 @@ "zuul-ngrok": "gnandretta/zuul-ngrok#upgrade-ngrok" }, "dependencies": { - "auth0-js": "8.0.0", + "auth0-js": "8.0.1", "blueimp-md5": "2.3.1", "fbjs": "^0.3.1", "immutable": "^3.7.3", From 241c31e4eb2c234e350f85547fd08aa7376e16b4 Mon Sep 17 00:00:00 2001 From: German Lena Date: Wed, 4 Jan 2017 16:29:11 -0300 Subject: [PATCH 3/3] fix version in bower --- bower.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 142ee8fa9..f23b5e653 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "auth0-lock", - "version": "10.8.0-beta.1", + "version": "10.8.0-beta.5", "main": "build/lock.js", "ignore": [ "lib-cov",