@jcoreio/auth0-meteor
Advanced tools
@@ -6,3 +6,3 @@ 'use strict'; | ||
}); | ||
exports.UserUpdater = undefined; | ||
exports.Params = exports.UserUpdater = undefined; | ||
@@ -69,9 +69,14 @@ var _regenerator = require('babel-runtime/regenerator'); | ||
var Params = _flowRuntime2.default.type('Params', _flowRuntime2.default.object(_flowRuntime2.default.property('clientId', _flowRuntime2.default.string()), _flowRuntime2.default.property('clientSecret', _flowRuntime2.default.string()), _flowRuntime2.default.property('domain', _flowRuntime2.default.string()), _flowRuntime2.default.property('audience', _flowRuntime2.default.string(), true), _flowRuntime2.default.property('jwksClientOptions', _flowRuntime2.default.object(_flowRuntime2.default.property('jwksUri', _flowRuntime2.default.string()), _flowRuntime2.default.property('strictSsl', _flowRuntime2.default.boolean(), true), _flowRuntime2.default.property('cache', _flowRuntime2.default.boolean(), true), _flowRuntime2.default.property('cacheMaxAge', _flowRuntime2.default.number(), true), _flowRuntime2.default.property('rateLimit', _flowRuntime2.default.boolean(), true), _flowRuntime2.default.property('jwksRequestsPerMinute', _flowRuntime2.default.number(), true)), true), _flowRuntime2.default.property('updaters', _flowRuntime2.default.array(UserUpdater), true))); | ||
var Params = exports.Params = _flowRuntime2.default.type('Params', _flowRuntime2.default.object(_flowRuntime2.default.property('clientId', _flowRuntime2.default.string()), _flowRuntime2.default.property('clientSecret', _flowRuntime2.default.string()), _flowRuntime2.default.property('domain', _flowRuntime2.default.string()), _flowRuntime2.default.property('audience', _flowRuntime2.default.string(), true), _flowRuntime2.default.property('jwksClientOptions', _flowRuntime2.default.object(_flowRuntime2.default.property('jwksUri', _flowRuntime2.default.string()), _flowRuntime2.default.property('strictSsl', _flowRuntime2.default.boolean(), true), _flowRuntime2.default.property('cache', _flowRuntime2.default.boolean(), true), _flowRuntime2.default.property('cacheMaxAge', _flowRuntime2.default.number(), true), _flowRuntime2.default.property('rateLimit', _flowRuntime2.default.boolean(), true), _flowRuntime2.default.property('jwksRequestsPerMinute', _flowRuntime2.default.number(), true)), true), _flowRuntime2.default.property('updaters', _flowRuntime2.default.array(UserUpdater), true))); | ||
function auth0LoginHandler(params) { | ||
var handler = function () { | ||
var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(options) { | ||
var auth0, idToken, _jwt$decode, header, payload, _ref2, publicKey, auth0UserId, mgmtClient, _profile, updated_at, created_at, last_login, parsedProfile, user, userId; | ||
function createLoginWithAuth0UserId(params) { | ||
var clientId = params.clientId, | ||
clientSecret = params.clientSecret, | ||
domain = params.domain; | ||
var updaters = params.updaters || []; | ||
return _flowRuntime2.default.annotate(function () { | ||
var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(auth0UserId) { | ||
var mgmtClient, profile, updated_at, created_at, last_login, parsedProfile, user, userId; | ||
return _regenerator2.default.wrap(function _callee$(_context) { | ||
@@ -81,18 +86,80 @@ while (1) { | ||
case 0: | ||
_context.next = 2; | ||
return (0, _getManagementClient2.default)({ clientId: clientId, clientSecret: clientSecret, domain: domain }); | ||
case 2: | ||
mgmtClient = _context.sent; | ||
_context.next = 5; | ||
return mgmtClient.users.get({ id: auth0UserId }); | ||
case 5: | ||
profile = _context.sent; | ||
updated_at = profile.updated_at, created_at = profile.created_at, last_login = profile.last_login; | ||
parsedProfile = (0, _extends3.default)({}, profile, { | ||
created_at: new Date(created_at), | ||
updated_at: new Date(updated_at), | ||
last_login: new Date(last_login) | ||
}); | ||
user = Meteor.users.findOne({ 'services.auth0.user_id': auth0UserId }, { fields: { _id: 1, 'services.auth0.updated_at': 1 } }); | ||
userId = void 0; | ||
if (user) { | ||
userId = user._id; | ||
if (user.services.auth0.updated_at < parsedProfile.updated_at) { | ||
Meteor.users.update({ _id: user._id }, { $set: { 'services.auth0': parsedProfile } }); | ||
updaters.forEach(function (updater) { | ||
return updater(user._id, profile); | ||
}); | ||
} | ||
} else { | ||
userId = Meteor.users.insert({ services: { auth0: parsedProfile } }); | ||
updaters.forEach(function (updater) { | ||
return updater(userId, profile); | ||
}); | ||
} | ||
return _context.abrupt('return', { type: 'auth0', userId: userId }); | ||
case 12: | ||
case 'end': | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, this); | ||
})); | ||
function loginWithAuth0UserId(_x) { | ||
return _ref.apply(this, arguments); | ||
} | ||
return loginWithAuth0UserId; | ||
}(), _flowRuntime2.default.function(_flowRuntime2.default.param('auth0UserId', _flowRuntime2.default.string()), _flowRuntime2.default.return(_flowRuntime2.default.ref('Promise', _flowRuntime2.default.ref(LoginResult))))); | ||
} | ||
_flowRuntime2.default.annotate(createLoginWithAuth0UserId, _flowRuntime2.default.function(_flowRuntime2.default.param('params', Params), _flowRuntime2.default.return(_flowRuntime2.default.function(_flowRuntime2.default.param('auth0UserId', _flowRuntime2.default.string()), _flowRuntime2.default.return(_flowRuntime2.default.ref('Promise', _flowRuntime2.default.ref(LoginResult))))))); | ||
function auth0LoginHandler(params) { | ||
var handler = function () { | ||
var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(options) { | ||
var auth0, idToken, _jwt$decode, header, payload, _ref3, publicKey, _auth0UserId; | ||
return _regenerator2.default.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
auth0 = options.auth0; | ||
if (auth0) { | ||
_context.next = 3; | ||
_context2.next = 3; | ||
break; | ||
} | ||
return _context.abrupt('return', undefined); | ||
return _context2.abrupt('return', undefined); | ||
case 3: | ||
if (!(Accounts.oauth.serviceNames().indexOf('auth0') < 0)) { | ||
_context.next = 5; | ||
_context2.next = 5; | ||
break; | ||
} | ||
return _context.abrupt('return', { | ||
return _context2.abrupt('return', { | ||
type: "auth0", | ||
@@ -106,17 +173,17 @@ error: new Error("No registered oauth service found for: Auth0") | ||
if (idToken) { | ||
_context.next = 8; | ||
_context2.next = 8; | ||
break; | ||
} | ||
return _context.abrupt('return', { type: 'auth0', error: new Error('missing idToken') }); | ||
return _context2.abrupt('return', { type: 'auth0', error: new Error('missing idToken') }); | ||
case 8: | ||
_context.prev = 8; | ||
_context2.prev = 8; | ||
_jwt$decode = _jsonwebtoken2.default.decode(idToken, { complete: true }), header = _jwt$decode.header, payload = _jwt$decode.payload; | ||
_context.next = 12; | ||
_context2.next = 12; | ||
return (0, _es6Promisify2.default)(jwksClient.getSigningKey)(header.kid); | ||
case 12: | ||
_ref2 = _context.sent; | ||
publicKey = _ref2.publicKey; | ||
_ref3 = _context2.sent; | ||
publicKey = _ref3.publicKey; | ||
@@ -128,64 +195,35 @@ _jsonwebtoken2.default.verify(idToken, publicKey, { | ||
auth0UserId = payload.sub; | ||
_auth0UserId = payload.sub; | ||
if (auth0UserId) { | ||
_context.next = 18; | ||
if (_auth0UserId) { | ||
_context2.next = 18; | ||
break; | ||
} | ||
return _context.abrupt('return', { type: 'auth0', error: new Error('missing sub in decoded idToken') }); | ||
return _context2.abrupt('return', { type: 'auth0', error: new Error('missing sub in decoded idToken') }); | ||
case 18: | ||
_context.next = 20; | ||
return (0, _getManagementClient2.default)({ clientId: clientId, clientSecret: clientSecret, domain: domain }); | ||
_context2.next = 20; | ||
return loginWithAuth0UserId(_auth0UserId); | ||
case 20: | ||
mgmtClient = _context.sent; | ||
_context.next = 23; | ||
return mgmtClient.users.get({ id: auth0UserId }); | ||
return _context2.abrupt('return', _context2.sent); | ||
case 23: | ||
_profile = _context.sent; | ||
updated_at = _profile.updated_at, created_at = _profile.created_at, last_login = _profile.last_login; | ||
parsedProfile = (0, _extends3.default)({}, _profile, { | ||
created_at: new Date(created_at), | ||
updated_at: new Date(updated_at), | ||
last_login: new Date(last_login) | ||
}); | ||
user = Meteor.users.findOne({ 'services.auth0.user_id': auth0UserId }, { fields: { _id: 1, 'services.auth0.updated_at': 1 } }); | ||
userId = void 0; | ||
_context2.prev = 23; | ||
_context2.t0 = _context2['catch'](8); | ||
if (user) { | ||
userId = user._id; | ||
if (user.services.auth0.updated_at < parsedProfile.updated_at) { | ||
Meteor.users.update({ _id: user._id }, { $set: { 'services.auth0': parsedProfile } }); | ||
updaters.forEach(function (updater) { | ||
return updater(user._id, _profile); | ||
}); | ||
} | ||
} else { | ||
userId = Meteor.users.insert({ services: { auth0: parsedProfile } }); | ||
updaters.forEach(function (updater) { | ||
return updater(userId, _profile); | ||
}); | ||
} | ||
return _context.abrupt('return', { type: 'auth0', userId: userId }); | ||
console.error(_context2.t0.stack); // eslint-disable-line no-console | ||
return _context2.abrupt('return', { type: 'auth0', error: _context2.t0 }); | ||
case 32: | ||
_context.prev = 32; | ||
_context.t0 = _context['catch'](8); | ||
console.error(_context.t0.stack); // eslint-disable-line no-console | ||
return _context.abrupt('return', { type: 'auth0', error: _context.t0 }); | ||
case 36: | ||
case 27: | ||
case 'end': | ||
return _context.stop(); | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee, this, [[8, 32]]); | ||
}, _callee2, this, [[8, 23]]); | ||
})); | ||
return function handler(_x) { | ||
return _ref.apply(this, arguments); | ||
return function handler(_x2) { | ||
return _ref2.apply(this, arguments); | ||
}; | ||
@@ -197,7 +235,6 @@ }(); | ||
domain = params.domain, | ||
updaters = params.updaters, | ||
audience = params.audience; | ||
var updaters = params.updaters || []; | ||
var jwksClient = (0, _jwksRsa2.default)(params.jwksClientOptions || { | ||
@@ -212,2 +249,4 @@ strictSsl: true, | ||
var loginWithAuth0UserId = createLoginWithAuth0UserId({ clientId: clientId, clientSecret: clientSecret, domain: domain, updaters: updaters }); | ||
_flowRuntime2.default.annotate(handler, _flowRuntime2.default.function(_flowRuntime2.default.param('options', _flowRuntime2.default.ref(LoginHandlerOptions)), _flowRuntime2.default.return(_flowRuntime2.default.ref('Promise', _flowRuntime2.default.nullable(_flowRuntime2.default.ref(LoginResult)))))); | ||
@@ -224,2 +263,4 @@ | ||
auth0LoginHandler.createLoginWithAuth0UserId = createLoginWithAuth0UserId; | ||
module.exports = auth0LoginHandler; |
{ | ||
"name": "@jcoreio/auth0-meteor", | ||
"version": "3.1.1", | ||
"version": "3.2.0", | ||
"description": "Auth0 integration with Meteor Accounts", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -22,4 +22,5 @@ # auth0-meteor | ||
import auth0LoginHandler from '@jcoreio/auth0-meteor/lib/server/auth0LoginHandler' | ||
import wrapResumeHandler from '@jcoreio/auth0-meteor/lib/server/wrapResumeHandler' | ||
Accounts.registerLoginHandler(auth0LoginHandler({ | ||
const auth0Params = { | ||
clientId: process.env.AUTH0_MANAGEMENT_CLIENT_ID, | ||
@@ -29,3 +30,6 @@ clientSecret: process.env.AUTH0_MANAGEMENT_CLIENT_SECRET, | ||
audience: process.env.AUTH0_FRONTEND_CLIENT_ID, | ||
})) | ||
} | ||
Accounts.registerLoginHandler(auth0LoginHandler(auth0Params)) | ||
wrapResumeHandler(auth0Params) | ||
``` | ||
@@ -32,0 +36,0 @@ |
@@ -16,3 +16,3 @@ // @flow | ||
type Params = { | ||
export type Params = { | ||
clientId: string, | ||
@@ -33,7 +33,43 @@ clientSecret: string, | ||
function createLoginWithAuth0UserId(params: Params): (auth0UserId: string) => Promise<LoginResult> { | ||
const {clientId, clientSecret, domain} = params | ||
const updaters = params.updaters || [] | ||
return async function loginWithAuth0UserId(auth0UserId: string): Promise<LoginResult> { | ||
const mgmtClient = await getManagementClient({clientId, clientSecret, domain}) | ||
const profile: UserProfile = await mgmtClient.users.get({id: auth0UserId}) | ||
const {updated_at, created_at, last_login} = profile | ||
const parsedProfile = { | ||
...profile, | ||
created_at: new Date(created_at), | ||
updated_at: new Date(updated_at), | ||
last_login: new Date(last_login), | ||
} | ||
const user = Meteor.users.findOne( | ||
{'services.auth0.user_id': auth0UserId}, | ||
{fields: {_id: 1, 'services.auth0.updated_at': 1}} | ||
) | ||
let userId | ||
if (user) { | ||
userId = user._id | ||
if (user.services.auth0.updated_at < parsedProfile.updated_at) { | ||
Meteor.users.update( | ||
{_id: user._id}, | ||
{$set: {'services.auth0': parsedProfile}} | ||
) | ||
updaters.forEach(updater => updater(user._id, profile)) | ||
} | ||
} else { | ||
userId = Meteor.users.insert({services: {auth0: parsedProfile}}) | ||
updaters.forEach(updater => updater(userId, profile)) | ||
} | ||
return {type: 'auth0', userId} | ||
} | ||
} | ||
function auth0LoginHandler(params: Params): LoginHandler { | ||
const {clientId, clientSecret, domain, audience} = params | ||
const {clientId, clientSecret, domain, updaters, audience} = params | ||
const updaters = params.updaters || [] | ||
const jwksClient = createJwksClient(params.jwksClientOptions || { | ||
@@ -48,2 +84,4 @@ strictSsl: true, | ||
const loginWithAuth0UserId = createLoginWithAuth0UserId({clientId, clientSecret, domain, updaters}) | ||
async function handler(options: LoginHandlerOptions): Promise<?LoginResult> { | ||
@@ -75,32 +113,3 @@ const {auth0} = options | ||
const mgmtClient = await getManagementClient({clientId, clientSecret, domain}) | ||
const profile: UserProfile = await mgmtClient.users.get({id: auth0UserId}) | ||
const {updated_at, created_at, last_login} = profile | ||
const parsedProfile = { | ||
...profile, | ||
created_at: new Date(created_at), | ||
updated_at: new Date(updated_at), | ||
last_login: new Date(last_login), | ||
} | ||
const user = Meteor.users.findOne( | ||
{'services.auth0.user_id': auth0UserId}, | ||
{fields: {_id: 1, 'services.auth0.updated_at': 1}} | ||
) | ||
let userId | ||
if (user) { | ||
userId = user._id | ||
if (user.services.auth0.updated_at < parsedProfile.updated_at) { | ||
Meteor.users.update( | ||
{_id: user._id}, | ||
{$set: {'services.auth0': parsedProfile}} | ||
) | ||
updaters.forEach(updater => updater(user._id, profile)) | ||
} | ||
} else { | ||
userId = Meteor.users.insert({services: {auth0: parsedProfile}}) | ||
updaters.forEach(updater => updater(userId, profile)) | ||
} | ||
return {type: 'auth0', userId} | ||
return await loginWithAuth0UserId(auth0UserId) | ||
} catch (error) { | ||
@@ -116,4 +125,5 @@ console.error(error.stack) // eslint-disable-line no-console | ||
} | ||
auth0LoginHandler.createLoginWithAuth0UserId = createLoginWithAuth0UserId | ||
module.exports = auth0LoginHandler | ||
234075
3.42%25
8.7%885
18.79%92
4.55%