mirror of
https://github.com/logto-io/logto.git
synced 2025-01-20 21:32:31 -05:00
2e08fa3816
* chore(core,locale): fix error messages * chore(core,locale): add input parameter guard and fix comment * chore(core,locale): add nonempty string guard for username
60 lines
1.7 KiB
TypeScript
60 lines
1.7 KiB
TypeScript
import { User, UsersPasswordEncryptionMethod } from '@logto/schemas';
|
|
import argon2 from 'argon2';
|
|
import pRetry from 'p-retry';
|
|
|
|
import { findUserByUsername, hasUserWithId, updateUserById } from '@/queries/user';
|
|
import assertThat from '@/utils/assert-that';
|
|
import { buildIdGenerator } from '@/utils/id';
|
|
import { encryptPassword } from '@/utils/password';
|
|
|
|
const userId = buildIdGenerator(12);
|
|
|
|
export const generateUserId = async (retries = 500) =>
|
|
pRetry(
|
|
async () => {
|
|
const id = userId();
|
|
|
|
if (!(await hasUserWithId(id))) {
|
|
return id;
|
|
}
|
|
|
|
throw new Error('Cannot generate user ID in reasonable retries');
|
|
},
|
|
{ retries, factor: 0 } // No need for exponential backoff
|
|
);
|
|
|
|
export const encryptUserPassword = async (
|
|
password: string
|
|
): Promise<{
|
|
passwordEncrypted: string;
|
|
passwordEncryptionMethod: UsersPasswordEncryptionMethod;
|
|
}> => {
|
|
const passwordEncryptionMethod = UsersPasswordEncryptionMethod.Argon2i;
|
|
const passwordEncrypted = await encryptPassword(
|
|
password,
|
|
|
|
passwordEncryptionMethod
|
|
);
|
|
|
|
return { passwordEncrypted, passwordEncryptionMethod };
|
|
};
|
|
|
|
export const findUserByUsernameAndPassword = async (
|
|
username: string,
|
|
password: string
|
|
): Promise<User> => {
|
|
const user = await findUserByUsername(username);
|
|
assertThat(user, 'user.username_not_exists');
|
|
const { passwordEncrypted, passwordEncryptionMethod } = user;
|
|
|
|
assertThat(passwordEncrypted && passwordEncryptionMethod, 'session.invalid_sign_in_method');
|
|
|
|
const result = await argon2.verify(passwordEncrypted, password);
|
|
|
|
assertThat(result, 'session.invalid_credentials');
|
|
|
|
return user;
|
|
};
|
|
|
|
export const updateLastSignInAt = async (userId: string) =>
|
|
updateUserById(userId, { lastSignInAt: Date.now() });
|