refactor: identity -> iam
This commit is contained in:
29
modules/iam/services/auth.ts
Normal file
29
modules/iam/services/auth.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { logger } from "@platform/logger";
|
||||
import { betterAuth } from "better-auth";
|
||||
import { mongodbAdapter } from "better-auth/adapters/mongodb";
|
||||
import { emailOTP } from "better-auth/plugins";
|
||||
|
||||
import { db } from "./database.ts";
|
||||
|
||||
export const auth = betterAuth({
|
||||
database: mongodbAdapter(db.db),
|
||||
session: {
|
||||
cookieCache: {
|
||||
enabled: true,
|
||||
maxAge: 5 * 60, // Cache duration in seconds
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
emailOTP({
|
||||
async sendVerificationOTP({ email, otp, type }) {
|
||||
if (type === "sign-in") {
|
||||
logger.info({ email, otp, type });
|
||||
} else if (type === "email-verification") {
|
||||
// Send the OTP for email verification
|
||||
} else {
|
||||
// Send the OTP for password reset
|
||||
}
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
61
modules/iam/services/database.ts
Normal file
61
modules/iam/services/database.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { getDatabaseAccessor } from "@platform/database/accessor.ts";
|
||||
|
||||
import {
|
||||
PRINCIPAL_TYPE_NAMES,
|
||||
type Principal,
|
||||
PrincipalSchema,
|
||||
PrincipalTypeId,
|
||||
parsePrincipal,
|
||||
} from "../models/principal.ts";
|
||||
|
||||
export const db = getDatabaseAccessor<{
|
||||
principal: Principal;
|
||||
}>("auth");
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------------
|
||||
| Methods
|
||||
|--------------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
export async function getPrincipalById(id: string): Promise<Principal | undefined> {
|
||||
return db
|
||||
.collection("principal")
|
||||
.findOne({ id })
|
||||
.then((value) => parsePrincipal(value));
|
||||
}
|
||||
|
||||
export async function setPrincipalRolesById(id: string, roles: string[]): Promise<void> {
|
||||
await db.collection("principal").updateOne({ id }, { $set: { roles } });
|
||||
}
|
||||
|
||||
export async function setPrincipalAttributesById(id: string, attr: Record<string, any>): Promise<void> {
|
||||
await db.collection("principal").updateOne({ id }, { $set: { attr } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a principal for a better-auth user.
|
||||
*
|
||||
* @param userId - User id from better-auth user list.
|
||||
*/
|
||||
export async function getPrincipalByUserId(userId: string): Promise<Principal> {
|
||||
const principal = await db.collection("principal").findOneAndUpdate(
|
||||
{ id: userId },
|
||||
{
|
||||
$setOnInsert: {
|
||||
id: userId,
|
||||
type: {
|
||||
id: PrincipalTypeId.User,
|
||||
name: PRINCIPAL_TYPE_NAMES[PrincipalTypeId.User],
|
||||
},
|
||||
roles: ["user"],
|
||||
attr: {},
|
||||
},
|
||||
},
|
||||
{ upsert: true, returnDocument: "after" },
|
||||
);
|
||||
if (principal === null) {
|
||||
throw new Error("Failed to resolve Principal");
|
||||
}
|
||||
return PrincipalSchema.parse(principal);
|
||||
}
|
||||
3
modules/iam/services/logger.ts
Normal file
3
modules/iam/services/logger.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { logger as platformLogger } from "@platform/logger";
|
||||
|
||||
export const logger = platformLogger.prefix("Modules/Identity");
|
||||
34
modules/iam/services/session.ts
Normal file
34
modules/iam/services/session.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import cookie from "cookie";
|
||||
|
||||
import { config } from "../config.ts";
|
||||
import { auth } from "./auth.ts";
|
||||
|
||||
/**
|
||||
* Get session headers which can be applied on a Response object to apply
|
||||
* an authenticated session to the respondent.
|
||||
*
|
||||
* @param accessToken - Token to apply to the cookie.
|
||||
* @param maxAge - Max age of the token.
|
||||
*/
|
||||
export async function getSessionHeaders(accessToken: string, maxAge: number): Promise<Headers> {
|
||||
return new Headers({
|
||||
"set-cookie": cookie.serialize(
|
||||
"better-auth.session_token",
|
||||
encodeURIComponent(accessToken), // URL-encode the token
|
||||
config.cookie(maxAge),
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get session container from request headers.
|
||||
*
|
||||
* @param headers - Request headers to extract session from.
|
||||
*/
|
||||
export async function getSessionByRequestHeader(headers: Headers) {
|
||||
const response = await auth.api.getSession({ headers });
|
||||
if (response === null) {
|
||||
return undefined;
|
||||
}
|
||||
return response.session;
|
||||
}
|
||||
Reference in New Issue
Block a user