Restructuring the folders (#1)
Co-authored-by: mifi <badmf@mifi.dev> Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
80
src/schema/auth.ts
Normal file
80
src/schema/auth.ts
Normal file
@@ -0,0 +1,80 @@
|
||||
import { Document, InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
|
||||
|
||||
import { Status } from '../constants/auth';
|
||||
import { COLL_STRATEGY } from '../constants/db';
|
||||
import { STRATEGIES } from '../constants/strategies';
|
||||
import { StrategyDocument } from './strategy';
|
||||
import { verify } from '../utils/password';
|
||||
|
||||
export interface Auth {
|
||||
is2FA?: boolean;
|
||||
record: StringSchemaDefinition;
|
||||
username: string;
|
||||
status: Status;
|
||||
strategies: Types.ObjectId[] | StrategyDocument[];
|
||||
}
|
||||
|
||||
interface AuthBaseDocument extends Auth, Document {
|
||||
authenticate(password: string): Promise<boolean>;
|
||||
getStrategy(method?: STRATEGIES): Promise<StrategyDocument | null>;
|
||||
}
|
||||
|
||||
export interface AuthDocument extends AuthBaseDocument {
|
||||
strategies: Types.ObjectId[];
|
||||
}
|
||||
|
||||
export interface AuthPopulatedDocument extends AuthBaseDocument {
|
||||
strategies: StrategyDocument[];
|
||||
}
|
||||
|
||||
export interface AuthModel extends Model<AuthDocument> {
|
||||
findByUsername(username: string): Promise<AuthDocument>;
|
||||
getLocalStrategyForUsername(username: string): Promise<StrategyDocument>;
|
||||
isUsernameAvailable(username: string): Promise<boolean>;
|
||||
}
|
||||
|
||||
export const AuthSchema = new Schema<AuthDocument, AuthModel>(
|
||||
{
|
||||
is2FA: { type: Boolean, default: false },
|
||||
record: { type: Types.ObjectId, unique: true },
|
||||
status: {
|
||||
type: Number,
|
||||
enum: Status,
|
||||
default: Status.UNVERIFIED,
|
||||
index: true,
|
||||
},
|
||||
strategies: [{ type: Types.ObjectId, ref: COLL_STRATEGY, default: [] }],
|
||||
username: { type: String, required: true, unique: true },
|
||||
},
|
||||
{
|
||||
minimize: true,
|
||||
timestamps: true,
|
||||
},
|
||||
);
|
||||
|
||||
AuthSchema.methods.authenticate = async function (this: AuthBaseDocument, password: string) {
|
||||
const strategy = await this.getStrategy();
|
||||
return !!strategy && verify(password, strategy.key);
|
||||
};
|
||||
|
||||
AuthSchema.methods.getStrategy = async function (this: AuthBaseDocument, method = STRATEGIES.LOCAL) {
|
||||
const doc = await this.populate<{ strategies: StrategyDocument[] }>('strategies');
|
||||
return doc.strategies.filter((strategy) => strategy.method === method).pop() || null;
|
||||
};
|
||||
|
||||
AuthSchema.statics = {
|
||||
async findByUsername(username) {
|
||||
return this.findOne({ username });
|
||||
},
|
||||
|
||||
async getLocalStrategyForUsername(username) {
|
||||
const doc = await this.findByUsername(username);
|
||||
return !!doc && doc.getStrategy();
|
||||
},
|
||||
|
||||
async isUsernameAvailable(username) {
|
||||
return !this.findByUsername(username);
|
||||
},
|
||||
};
|
||||
|
||||
export type AuthSchema = InferSchemaType<typeof AuthSchema>;
|
||||
Reference in New Issue
Block a user