import { Action } from '@mifi/auth-common/lib/enums/action'; import { Status } from '@mifi/auth-common/lib/enums/status'; import { STRATEGIES } from '@mifi/auth-common/lib/enums/strategies'; import { TokenType } from '@mifi/auth-common/lib/enums/tokens'; import { REQUIRE_VERIFICATION } from '@mifi/auth-common/lib/settings'; import { DatabaseError } from '@mifi/services-common/lib/domain/errors/DatabaseError'; import { Auth as AuthProps } from '../../schema/auth'; import { Auth, Log, Strategy, Token } from '../..'; type CreateProps = Pick & { externalId?: string; handle?: AuthProps['handle']; password?: string; publicKey?: string; record?: AuthProps['record']; }; export const create = async ({ record, username, externalId, handle, password, publicKey }: CreateProps) => { const status = REQUIRE_VERIFICATION ? Status.UNVERIFIED : Status.ACTIVE; const doc = await Auth.create({ handle, record, status, username, }).catch((err) => { throw new DatabaseError('failed to create user', { err }); }); if (doc) { const method = externalId && publicKey ? STRATEGIES.FIDO2 : STRATEGIES.LOCAL; const strategy = await Strategy.create({ externalId, key: password || publicKey, method, parent: doc._id, }).catch((err) => { throw new DatabaseError(`failed to create strategy ${STRATEGIES[method]}`, { err }); }); if (strategy) { doc.strategies.push(strategy._id); await doc.save(); Log.add(doc._id, Action.CREATE); return { doc, token: method === STRATEGIES.LOCAL && REQUIRE_VERIFICATION && (await Token.getToken(TokenType.VERIFICATION, doc._id)), }; } await doc.deleteOne((err) => { throw new DatabaseError('failed to remove invalid auth record', { err, doc, }); }); } return null; }; export type Fido2UserProps = Pick & { externalId: string; publicKey: string }; export const createFido2User = (props: Fido2UserProps) => create(props); export type LocalUserProps = Pick & { password: string }; export const createLocalUser = (props: LocalUserProps) => create(props);