Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@accounts/server

Package Overview
Dependencies
Maintainers
5
Versions
204
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@accounts/server - npm Package Compare versions

Comparing version 0.26.0-alpha.2 to 0.26.0-alpha.3

18

lib/accounts-mfa.d.ts

@@ -1,2 +0,2 @@

import { DatabaseInterface, Authenticator, AuthenticatorService, ConnectionInformations } from '@accounts/types';
import { DatabaseInterface, Authenticator, AuthenticatorService, ConnectionInformations, MfaChallenge } from '@accounts/types';
export declare class AccountsMFA {

@@ -9,3 +9,3 @@ private db;

/**
* @description Request a challenge for the MFA authentication
* @description Request a challenge for the MFA authentication.
* @param {string} mfaToken - A valid mfa token you obtained during the login process.

@@ -15,5 +15,5 @@ * @param {string} authenticatorId - The ID of the authenticator to challenge.

*/
challenge(mfaToken: string, authenticatorId: string, infos: ConnectionInformations): Promise<void>;
challenge(mfaToken: string, authenticatorId: string, infos: ConnectionInformations): Promise<any>;
/**
* @description Start the association of a new authenticator
* @description Start the association of a new authenticator.
* @param {string} userId - User id to link the new authenticator.

@@ -26,2 +26,11 @@ * @param {string} serviceName - Service name of the authenticator service.

/**
* @description Associate a new authenticator, this method is called when the user is enforced to
* associate an authenticator before the first login.
* @param {string} userId - User id to link the new authenticator.
* @param {string} serviceName - Service name of the authenticator service.
* @param {any} params - Params for the the authenticator service.
* @param {ConnectionInformations} infos - User connection informations.
*/
associateByMfaToken(mfaToken: string, serviceName: string, params: any, infos: ConnectionInformations): Promise<any>;
/**
* @description Return the list of the active and inactive authenticators for this user.

@@ -38,2 +47,3 @@ * The authenticators objects are whitelisted to not expose any sensitive informations to the client.

findUserAuthenticatorsByMfaToken(mfaToken: string): Promise<Authenticator[]>;
isMfaChallengeValid(mfaChallenge: MfaChallenge): boolean;
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var tokens_1 = require("./utils/tokens");
var AccountsMFA = /** @class */ (function () {

@@ -11,3 +10,3 @@ function AccountsMFA(db, authenticators) {

/**
* @description Request a challenge for the MFA authentication
* @description Request a challenge for the MFA authentication.
* @param {string} mfaToken - A valid mfa token you obtained during the login process.

@@ -33,3 +32,3 @@ * @param {string} authenticatorId - The ID of the authenticator to challenge.

// TODO need to check that the challenge is not expired
if (!mfaChallenge || mfaChallenge.deactivated) {
if (!mfaChallenge || !this.isMfaChallengeValid(mfaChallenge)) {
throw new Error('Mfa token invalid');

@@ -51,16 +50,10 @@ }

}
if (!authenticatorService.challenge) return [3 /*break*/, 4];
return [4 /*yield*/, authenticatorService.challenge(mfaChallenge, authenticator, infos)];
if (!!authenticatorService.challenge) return [3 /*break*/, 4];
return [4 /*yield*/, this.db.updateMfaChallenge(mfaChallenge.id, {
authenticatorId: authenticator.id,
})];
case 3:
_a.sent();
_a.label = 4;
case 4:
// Then we attach the authenticator id that will be used to resolve the challenge
return [4 /*yield*/, this.db.updateMfaChallenge(mfaChallenge.id, {
authenticatorId: authenticator.id,
})];
case 5:
// Then we attach the authenticator id that will be used to resolve the challenge
_a.sent();
return [2 /*return*/];
return [2 /*return*/, null];
case 4: return [2 /*return*/, authenticatorService.challenge(mfaChallenge, authenticator, infos)];
}

@@ -71,3 +64,3 @@ });

/**
* @description Start the association of a new authenticator
* @description Start the association of a new authenticator.
* @param {string} userId - User id to link the new authenticator.

@@ -80,3 +73,3 @@ * @param {string} serviceName - Service name of the authenticator service.

return tslib_1.__awaiter(this, void 0, void 0, function () {
var associate, mfaChallengeToken;
var associate;
return tslib_1.__generator(this, function (_a) {

@@ -91,14 +84,39 @@ switch (_a.label) {

associate = _a.sent();
mfaChallengeToken = tokens_1.generateRandomToken();
// associate.id refer to the authenticator id
return [4 /*yield*/, this.db.createMfaChallenge({
userId: userId,
authenticatorId: associate.id,
token: mfaChallengeToken,
scope: 'associate',
})];
return [2 /*return*/, associate];
}
});
});
};
/**
* @description Associate a new authenticator, this method is called when the user is enforced to
* associate an authenticator before the first login.
* @param {string} userId - User id to link the new authenticator.
* @param {string} serviceName - Service name of the authenticator service.
* @param {any} params - Params for the the authenticator service.
* @param {ConnectionInformations} infos - User connection informations.
*/
AccountsMFA.prototype.associateByMfaToken = function (mfaToken, serviceName, params, infos) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var mfaChallenge, associate;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.authenticators[serviceName]) {
throw new Error("No authenticator with the name " + serviceName + " was registered.");
}
if (!mfaToken) {
throw new Error('Mfa token invalid');
}
return [4 /*yield*/, this.db.findMfaChallengeByToken(mfaToken)];
case 1:
mfaChallenge = _a.sent();
if (!mfaChallenge ||
!this.isMfaChallengeValid(mfaChallenge) ||
mfaChallenge.scope !== 'associate') {
throw new Error('Mfa token invalid');
}
return [4 /*yield*/, this.authenticators[serviceName].associate(mfaChallenge, params, infos)];
case 2:
// associate.id refer to the authenticator id
_a.sent();
return [2 /*return*/, tslib_1.__assign(tslib_1.__assign({}, associate), { mfaToken: mfaChallengeToken })];
associate = _a.sent();
return [2 /*return*/, associate];
}

@@ -151,4 +169,3 @@ });

mfaChallenge = _a.sent();
// TODO need to check that the challenge is not expired
if (!mfaChallenge || mfaChallenge.deactivated) {
if (!mfaChallenge || !this.isMfaChallengeValid(mfaChallenge)) {
throw new Error('Mfa token invalid');

@@ -172,2 +189,9 @@ }

};
AccountsMFA.prototype.isMfaChallengeValid = function (mfaChallenge) {
// TODO need to check that the challenge is not expired
if (mfaChallenge.deactivated) {
return false;
}
return true;
};
return AccountsMFA;

@@ -174,0 +198,0 @@ }());

@@ -23,5 +23,6 @@ import Emittery from 'emittery';

useInternalUserObjectSanitizer: boolean;
enforceMfaForLogin: boolean;
};
export declare class AccountsServer {
options: AccountsServerOptions & typeof defaultOptions;
export declare class AccountsServer<CustomUser extends User = User> {
options: AccountsServerOptions<CustomUser> & typeof defaultOptions;
mfa: AccountsMFA;

@@ -32,4 +33,4 @@ private services;

private hooks;
constructor(options: AccountsServerOptions, services: {
[key: string]: AuthenticationService;
constructor(options: AccountsServerOptions<CustomUser>, services: {
[key: string]: AuthenticationService<CustomUser>;
}, authenticators?: {

@@ -70,3 +71,3 @@ [key: string]: AuthenticatorService;

*/
loginWithUser(user: User, infos: ConnectionInformations): Promise<LoginResult>;
loginWithUser(user: CustomUser, infos: ConnectionInformations): Promise<LoginResult>;
/**

@@ -115,3 +116,3 @@ * @description Impersonate to another user.

*/
resumeSession(accessToken: string): Promise<User>;
resumeSession(accessToken: string): Promise<CustomUser>;
/**

@@ -129,3 +130,3 @@ * @description Find a session by his token.

*/
findUserById(userId: string): Promise<User | null>;
findUserById(userId: string): Promise<CustomUser | null>;
/**

@@ -143,4 +144,4 @@ * @description Deactivate a user, the user will not be able to login until his account is reactivated.

activateUser(userId: string): Promise<void>;
prepareMail(to: string, token: string, user: User, pathFragment: string, emailTemplate: EmailTemplateType, from: string): any;
sanitizeUser(user: User): User;
prepareMail(to: string, token: string, user: CustomUser, pathFragment: string, emailTemplate: EmailTemplateType, from: string): any;
sanitizeUser(user: CustomUser): CustomUser;
/**

@@ -147,0 +148,0 @@ * Private methods

@@ -30,2 +30,3 @@ "use strict";

useInternalUserObjectSanitizer: true,
enforceMfaForLogin: false,
};

@@ -135,3 +136,3 @@ var AccountsServer = /** @class */ (function () {

return tslib_1.__awaiter(this, void 0, void 0, function () {
var hooksInfo, mfaToken, mfaChallenge, authenticator, user_1, loginResult_1, user, authenticators, activeAuthenticator, mfaChallengeToken, loginResult, err_2;
var hooksInfo, mfaToken, mfaChallenge, authenticator, user_1, loginResult_1, user, authenticators, activeAuthenticator, mfaChallengeToken, mfaChallengeToken, loginResult, err_2;
return tslib_1.__generator(this, function (_a) {

@@ -150,3 +151,3 @@ switch (_a.label) {

case 1:
_a.trys.push([1, 18, , 19]);
_a.trys.push([1, 20, , 21]);
if (!(serviceName === 'mfa')) return [3 /*break*/, 11];

@@ -235,18 +236,29 @@ mfaToken = params.mfaToken;

return [2 /*return*/, { mfaToken: mfaChallengeToken }];
case 15:
case 15:
if (!this.options.enforceMfaForLogin) return [3 /*break*/, 17];
mfaChallengeToken = tokens_1.generateRandomToken();
return [4 /*yield*/, this.db.createMfaChallenge({
userId: user.id,
token: mfaChallengeToken,
scope: 'associate',
})];
case 16:
_a.sent();
return [2 /*return*/, { mfaToken: mfaChallengeToken }];
case 17:
// Let the user validate the login attempt
return [4 /*yield*/, this.hooks.emitSerial(server_hooks_1.ServerHooks.ValidateLogin, hooksInfo)];
case 16:
case 18:
// Let the user validate the login attempt
_a.sent();
return [4 /*yield*/, this.loginWithUser(user, infos)];
case 17:
case 19:
loginResult = _a.sent();
this.hooks.emit(server_hooks_1.ServerHooks.LoginSuccess, hooksInfo);
return [2 /*return*/, loginResult];
case 18:
case 20:
err_2 = _a.sent();
this.hooks.emit(server_hooks_1.ServerHooks.LoginError, tslib_1.__assign(tslib_1.__assign({}, hooksInfo), { error: err_2 }));
throw err_2;
case 19: return [2 /*return*/];
case 21: return [2 /*return*/];
}

@@ -253,0 +265,0 @@ });

@@ -9,3 +9,3 @@ import * as jwt from 'jsonwebtoken';

import { TokenCreator } from './token-creator';
export interface AccountsServerOptions {
export interface AccountsServerOptions<CustomUser extends User = User> {
/**

@@ -15,3 +15,3 @@ * Return ambiguous error messages from login failures to prevent user enumeration. Defaults to true.

ambiguousErrorMessages?: boolean;
db?: DatabaseInterface;
db?: DatabaseInterface<CustomUser>;
tokenSecret: string | {

@@ -47,2 +47,7 @@ publicKey: jwt.Secret;

useInternalUserObjectSanitizer?: boolean;
/**
* If set to true, the user will be asked to register a new MFA authenticator the first time
* he tries to login.
*/
enforceMfaForLogin?: boolean;
}
{
"name": "@accounts/server",
"version": "0.26.0-alpha.2",
"version": "0.26.0-alpha.3",
"description": "Fullstack authentication and accounts-management",

@@ -43,3 +43,3 @@ "main": "lib/index.js",

"dependencies": {
"@accounts/types": "^0.26.0-alpha.2",
"@accounts/types": "^0.26.0-alpha.3",
"@types/jsonwebtoken": "8.3.5",

@@ -59,3 +59,3 @@ "emittery": "0.5.1",

},
"gitHead": "ad0914817551b832a11600613981ae5dba11c09d"
"gitHead": "c117b8980f2153d497be744f1280bb2db2470514"
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc