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

@accounts/password

Package Overview
Dependencies
Maintainers
5
Versions
139
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@accounts/password - npm Package Compare versions

Comparing version 0.1.0-beta.5 to 0.1.0-beta.6

__tests__/utils/encryption.ts

34

__tests__/accounts-password.ts

@@ -34,8 +34,6 @@ import { set } from 'lodash';

const user = {
services: {}
services: {},
};
const tmpAccountsPassword = new AccountsPassword({});
tmpAccountsPassword.passwordAuthenticator = jest.fn(() =>
Promise.resolve(user)
);
tmpAccountsPassword.passwordAuthenticator = jest.fn(() => Promise.resolve(user));
const ret = await tmpAccountsPassword.authenticate({

@@ -135,5 +133,3 @@ user: 'toto',

const email = 'john.doe@gmail.com';
set(validUser, 'services.email.verificationTokens', [
{ token, address: email },
]);
set(validUser, 'services.email.verificationTokens', [{ token, address: email }]);
validUser.emails = [{ address: email }];

@@ -155,5 +151,3 @@ const invalidUser = { ...validUser };

it('throws when token not found', async () => {
const findUserByEmailVerificationToken = jest.fn(() =>
Promise.resolve({})
);
const findUserByEmailVerificationToken = jest.fn(() => Promise.resolve({}));
password.setStore({ findUserByEmailVerificationToken } as any);

@@ -169,5 +163,3 @@ try {

it('throws when email not found', async () => {
const findUserByEmailVerificationToken = jest.fn(() =>
Promise.resolve(invalidUser)
);
const findUserByEmailVerificationToken = jest.fn(() => Promise.resolve(invalidUser));
password.setStore({ findUserByEmailVerificationToken } as any);

@@ -183,5 +175,3 @@ try {

it('call this.db.verifyEmail', async () => {
const findUserByEmailVerificationToken = jest.fn(() =>
Promise.resolve(validUser)
);
const findUserByEmailVerificationToken = jest.fn(() => Promise.resolve(validUser));
const verifyEmail = jest.fn(() => Promise.resolve());

@@ -221,5 +211,3 @@ password.setStore({

it('throws when token is expired', async () => {
const findUserByResetPasswordToken = jest.fn(() =>
Promise.resolve(invalidUser)
);
const findUserByResetPasswordToken = jest.fn(() => Promise.resolve(invalidUser));
const isTokenExpired = jest.fn(() => true);

@@ -237,5 +225,3 @@ password.setStore({ findUserByResetPasswordToken } as any);

it('throws when token have invalid email', async () => {
const findUserByResetPasswordToken = jest.fn(() =>
Promise.resolve(invalidUser)
);
const findUserByResetPasswordToken = jest.fn(() => Promise.resolve(invalidUser));
const isTokenExpired = jest.fn(() => false);

@@ -253,5 +239,3 @@ password.setStore({ findUserByResetPasswordToken } as any);

it('reset password and invalidate all sessions', async () => {
const findUserByResetPasswordToken = jest.fn(() =>
Promise.resolve(validUser)
);
const findUserByResetPasswordToken = jest.fn(() => Promise.resolve(validUser));
const isTokenExpired = jest.fn(() => false);

@@ -258,0 +242,0 @@ const setResetPassword = jest.fn(() => Promise.resolve());

@@ -1,6 +0,8 @@

import { CreateUserType, UserObjectType, HashAlgorithm } from '@accounts/common';
import { DBInterface, AccountsServer, AuthService } from '@accounts/server';
import { CreateUser, User, DatabaseInterface, AuthenticationService } from '@accounts/types';
import { HashAlgorithm } from '@accounts/common';
import { TwoFactor, AccountsTwoFactorOptions } from '@accounts/two-factor';
import { PasswordCreateUserType, PasswordLoginType, PasswordType } from './types';
export declare const isEmail: (email?: string) => boolean;
import { AccountsServer } from '@accounts/server';
import { PasswordCreateUserType } from './types/password-create-user-type';
import { PasswordLoginType } from './types/password-login-type';
import { PasswordType } from './types/password-type';
export interface AccountsPasswordOptions {

@@ -12,3 +14,3 @@ twoFactor?: AccountsTwoFactorOptions;

minimumPasswordLength?: number;
validateNewUser?: (user: CreateUserType) => Promise<boolean>;
validateNewUser?: (user: CreateUser) => Promise<boolean>;
validateEmail?(email?: string): boolean;

@@ -18,3 +20,3 @@ validatePassword?(password?: PasswordType): boolean;

}
export default class AccountsPassword implements AuthService {
export default class AccountsPassword implements AuthenticationService {
serviceName: string;

@@ -26,6 +28,6 @@ server: AccountsServer;

constructor(options?: AccountsPasswordOptions);
setStore(store: DBInterface): void;
authenticate(params: PasswordLoginType): Promise<UserObjectType>;
findUserByEmail(email: string): Promise<UserObjectType | null>;
findUserByUsername(username: string): Promise<UserObjectType | null>;
setStore(store: DatabaseInterface): void;
authenticate(params: PasswordLoginType): Promise<User>;
findUserByEmail(email: string): Promise<User | null>;
findUserByUsername(username: string): Promise<User | null>;
addEmail(userId: string, newEmail: string, verified: boolean): Promise<void>;

@@ -32,0 +34,0 @@ removeEmail(userId: string, email: string): Promise<void>;

@@ -47,10 +47,6 @@ "use strict";

var lodash_1 = require("lodash");
var two_factor_1 = require("@accounts/two-factor");
var server_1 = require("@accounts/server");
var two_factor_1 = require("@accounts/two-factor");
var utils_1 = require("@accounts/server/lib/utils");
var encryption_1 = require("./encryption");
exports.isEmail = function (email) {
var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return email && re.test(email);
};
var encryption_1 = require("./utils/encryption");
var isEmail_1 = require("./utils/isEmail");
var defaultOptions = {

@@ -61,3 +57,3 @@ passwordResetTokenExpirationInDays: 3,

validateEmail: function (email) {
var isValid = !lodash_1.isEmpty(lodash_1.trim(email || '')) && exports.isEmail(email);
var isValid = !lodash_1.isEmpty(lodash_1.trim(email || '')) && isEmail_1.isEmail(email);
return Boolean(isValid);

@@ -244,3 +240,3 @@ },

}
address = utils_1.getFirstUserEmail(user, address);
address = server_1.getFirstUserEmail(user, address);
token = server_1.generateRandomToken();

@@ -270,3 +266,3 @@ return [4, this.db.addResetPasswordToken(user.id, address, token)];

}
address = utils_1.getFirstUserEmail(user, address);
address = server_1.getFirstUserEmail(user, address);
token = server_1.generateRandomToken();

@@ -291,4 +287,3 @@ return [4, this.db.addResetPasswordToken(user.id, address, token, 'enroll')];

case 0:
if (!this.options.validateUsername(user.username) &&
!this.options.validateEmail(user.email)) {
if (!this.options.validateUsername(user.username) && !this.options.validateEmail(user.email)) {
throw new Error('Username or Email is required');

@@ -384,5 +379,3 @@ }

hashAlgorithm = this.options.passwordHashAlgorithm;
pass = hashAlgorithm
? encryption_1.hashPassword(password, hashAlgorithm)
: password;
pass = hashAlgorithm ? encryption_1.hashPassword(password, hashAlgorithm) : password;
return [4, encryption_1.verifyPassword(pass, hash)];

@@ -404,5 +397,3 @@ case 8:

hashAlgorithm = this.options.passwordHashAlgorithm;
hashedPassword = hashAlgorithm
? encryption_1.hashPassword(password, hashAlgorithm)
: password;
hashedPassword = hashAlgorithm ? encryption_1.hashPassword(password, hashAlgorithm) : password;
return [2, encryption_1.bcryptPassword(hashedPassword)];

@@ -415,3 +406,3 @@ });

if (user && !username && !email) {
if (exports.isEmail(user)) {
if (isEmail_1.isEmail(user)) {
email = user;

@@ -418,0 +409,0 @@ username = null;

{
"name": "@accounts/password",
"version": "0.1.0-beta.5",
"version": "0.1.0-beta.6",
"license": "MIT",

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

"dependencies": {
"@accounts/two-factor": "^0.1.0-beta.5",
"@accounts/two-factor": "^0.1.0-beta.6",
"bcryptjs": "^2.4.3",

@@ -34,6 +34,7 @@ "lodash": "^4.17.4"

"devDependencies": {
"@accounts/common": "^0.1.0-beta.5",
"@accounts/server": "^0.1.0-beta.5",
"@accounts/common": "^0.1.0-beta.6",
"@accounts/server": "^0.1.0-beta.6",
"@accounts/types": "^0.1.0-beta.6",
"@types/bcryptjs": "2.4.1",
"@types/lodash": "4.14.104",
"@types/lodash": "4.14.105",
"rimraf": "2.6.2"

@@ -40,0 +41,0 @@ },

@@ -1,39 +0,14 @@

import {
trim,
isEmpty,
isFunction,
isString,
isPlainObject,
get,
find,
includes,
} from 'lodash';
import {
CreateUserType,
UserObjectType,
HashAlgorithm,
LoginUserIdentityType,
EmailRecord,
TokenRecord,
} from '@accounts/common';
import {
DBInterface,
AccountsServer,
generateRandomToken,
AuthService,
} from '@accounts/server';
import { trim, isEmpty, isFunction, isString, isPlainObject, get, find, includes } from 'lodash';
import { CreateUser, User, Login, EmailRecord, TokenRecord, DatabaseInterface, AuthenticationService } from '@accounts/types';
import { HashAlgorithm } from '@accounts/common';
import { TwoFactor, AccountsTwoFactorOptions } from '@accounts/two-factor';
import { getFirstUserEmail } from '@accounts/server/lib/utils';
import { hashPassword, bcryptPassword, verifyPassword } from './encryption';
import {
PasswordCreateUserType,
PasswordLoginType,
PasswordType,
} from './types';
import { AccountsServer, generateRandomToken, getFirstUserEmail } from '@accounts/server';
import { hashPassword, bcryptPassword, verifyPassword } from './utils/encryption';
export const isEmail = (email?: string) => {
const re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return email && re.test(email);
};
import { PasswordCreateUserType } from './types/password-create-user-type';
import { PasswordLoginType } from './types/password-login-type';
import { PasswordType } from './types/password-type';
import { isEmail } from './utils/isEmail';
export interface AccountsPasswordOptions {

@@ -45,3 +20,3 @@ twoFactor?: AccountsTwoFactorOptions;

minimumPasswordLength?: number;
validateNewUser?: (user: CreateUserType) => Promise<boolean>;
validateNewUser?: (user: CreateUser) => Promise<boolean>;
validateEmail?(email?: string): boolean;

@@ -66,4 +41,3 @@ validatePassword?(password?: PasswordType): boolean;

const usernameRegex = /^[a-zA-Z][a-zA-Z0-9]*$/;
const isValid =
username && !isEmpty(trim(username)) && usernameRegex.test(username);
const isValid = username && !isEmpty(trim(username)) && usernameRegex.test(username);
return Boolean(isValid);

@@ -73,3 +47,3 @@ },

export default class AccountsPassword implements AuthService {
export default class AccountsPassword implements AuthenticationService {
public serviceName = 'password';

@@ -79,3 +53,3 @@ public server: AccountsServer;

private options: AccountsPasswordOptions;
private db: DBInterface;
private db: DatabaseInterface;

@@ -87,3 +61,3 @@ constructor(options: AccountsPasswordOptions = {}) {

public setStore(store: DBInterface) {
public setStore(store: DatabaseInterface) {
this.db = store;

@@ -93,5 +67,3 @@ this.twoFactor.setStore(store);

public async authenticate(
params: PasswordLoginType
): Promise<UserObjectType> {
public async authenticate(params: PasswordLoginType): Promise<User> {
const { user, password, code } = params;

@@ -120,3 +92,3 @@ if (!user || !password) {

*/
public findUserByEmail(email: string): Promise<UserObjectType | null> {
public findUserByEmail(email: string): Promise<User | null> {
return this.db.findUserByEmail(email);

@@ -130,3 +102,3 @@ }

*/
public findUserByUsername(username: string): Promise<UserObjectType | null> {
public findUserByUsername(username: string): Promise<User | null> {
return this.db.findUserByUsername(username);

@@ -144,7 +116,3 @@ }

*/
public addEmail(
userId: string,
newEmail: string,
verified: boolean
): Promise<void> {
public addEmail(userId: string, newEmail: string, verified: boolean): Promise<void> {
// TODO use this.options.verifyEmail before

@@ -181,6 +149,3 @@ return this.db.addEmail(userId, newEmail, verified);

);
const tokenRecord = find(
verificationTokens,
(t: TokenRecord) => t.token === token
);
const tokenRecord = find(verificationTokens, (t: TokenRecord) => t.token === token);
if (!tokenRecord) {

@@ -190,6 +155,3 @@ throw new Error('Verify email link expired');

// TODO check time for expiry date
const emailRecord = find(
user.emails,
(e: EmailRecord) => e.address === tokenRecord.address
);
const emailRecord = find(user.emails, (e: EmailRecord) => e.address === tokenRecord.address);
if (!emailRecord) {

@@ -207,6 +169,3 @@ throw new Error('Verify email link is for unknown address');

*/
public async resetPassword(
token: string,
newPassword: PasswordType
): Promise<void> {
public async resetPassword(token: string, newPassword: PasswordType): Promise<void> {
const user = await this.db.findUserByResetPasswordToken(token);

@@ -226,8 +185,3 @@ if (!user) {

const emails = user.emails || [];
if (
!includes(
emails.map((email: EmailRecord) => email.address),
resetTokenRecord.address
)
) {
if (!includes(emails.map((email: EmailRecord) => email.address), resetTokenRecord.address)) {
throw new Error('Token has invalid email address');

@@ -238,8 +192,3 @@ }

// Change the user password and remove the old token
await this.db.setResetPassword(
user.id,
resetTokenRecord.address,
password,
token
);
await this.db.setResetPassword(user.id, resetTokenRecord.address, password, token);
// Changing the password should invalidate existing sessions

@@ -360,6 +309,3 @@ this.db.invalidateAllSessions(user.id);

public async createUser(user: PasswordCreateUserType): Promise<string> {
if (
!this.options.validateUsername(user.username) &&
!this.options.validateEmail(user.email)
) {
if (!this.options.validateUsername(user.username) && !this.options.validateEmail(user.email)) {
throw new Error('Username or Email is required');

@@ -392,6 +338,3 @@ }

const { validateNewUser } = this.options;
if (
isFunction(validateNewUser) &&
!await validateNewUser(proposedUserObject)
) {
if (isFunction(validateNewUser) && !await validateNewUser(proposedUserObject)) {
throw new Error('User invalid');

@@ -404,5 +347,5 @@ }

private async passwordAuthenticator(
user: string | LoginUserIdentityType,
user: string | Login,
password: PasswordType
): Promise<UserObjectType> {
): Promise<User> {
const { username, email, id } = isString(user)

@@ -412,3 +355,3 @@ ? this.toUsernameAndEmail({ user })

let foundUser: UserObjectType;
let foundUser: User;

@@ -436,5 +379,3 @@ if (id) {

const hashAlgorithm = this.options.passwordHashAlgorithm;
const pass: any = hashAlgorithm
? hashPassword(password, hashAlgorithm)
: password;
const pass: any = hashAlgorithm ? hashPassword(password, hashAlgorithm) : password;
const isPasswordValid = await verifyPassword(pass, hash);

@@ -451,5 +392,3 @@

const hashAlgorithm = this.options.passwordHashAlgorithm;
const hashedPassword: any = hashAlgorithm
? hashPassword(password, hashAlgorithm)
: password;
const hashedPassword: any = hashAlgorithm ? hashPassword(password, hashAlgorithm) : password;
return bcryptPassword(hashedPassword);

@@ -456,0 +395,0 @@ }

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