@arch-cadre/core 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/_rolldown/runtime.cjs +29 -0
- package/dist/_virtual/_rolldown/runtime.mjs +18 -0
- package/dist/core/auth/augment.cjs +71 -0
- package/dist/core/auth/augment.d.cts +20 -0
- package/dist/core/auth/augment.d.cts.map +1 -0
- package/dist/core/auth/augment.d.mts +20 -0
- package/dist/core/auth/augment.d.mts.map +1 -0
- package/dist/core/auth/augment.mjs +66 -0
- package/dist/core/auth/augment.mjs.map +1 -0
- package/dist/core/auth/email-verification.cjs +99 -0
- package/dist/core/auth/email-verification.d.cts +62 -0
- package/dist/core/auth/email-verification.d.cts.map +1 -0
- package/dist/core/auth/email-verification.d.mts +62 -0
- package/dist/core/auth/email-verification.d.mts.map +1 -0
- package/dist/core/auth/email-verification.mjs +92 -0
- package/dist/core/auth/email-verification.mjs.map +1 -0
- package/dist/core/auth/logic.cjs +224 -0
- package/dist/core/auth/logic.d.cts +110 -0
- package/dist/core/auth/logic.d.cts.map +1 -0
- package/dist/core/auth/logic.d.mts +110 -0
- package/dist/core/auth/logic.d.mts.map +1 -0
- package/dist/core/auth/logic.mjs +213 -0
- package/dist/core/auth/logic.mjs.map +1 -0
- package/dist/core/auth/password-reset.cjs +118 -0
- package/dist/core/auth/password-reset.d.cts +39 -0
- package/dist/core/auth/password-reset.d.cts.map +1 -0
- package/dist/core/auth/password-reset.d.mts +39 -0
- package/dist/core/auth/password-reset.d.mts.map +1 -0
- package/dist/core/auth/password-reset.mjs +111 -0
- package/dist/core/auth/password-reset.mjs.map +1 -0
- package/dist/core/auth/rbac.cjs +118 -0
- package/dist/core/auth/rbac.d.cts +61 -0
- package/dist/core/auth/rbac.d.cts.map +1 -0
- package/dist/core/auth/rbac.d.mts +61 -0
- package/dist/core/auth/rbac.d.mts.map +1 -0
- package/dist/core/auth/rbac.mjs +104 -0
- package/dist/core/auth/rbac.mjs.map +1 -0
- package/dist/core/auth/session.cjs +161 -0
- package/dist/core/auth/session.d.cts +54 -0
- package/dist/core/auth/session.d.cts.map +1 -0
- package/dist/core/auth/session.d.mts +54 -0
- package/dist/core/auth/session.d.mts.map +1 -0
- package/dist/core/auth/session.mjs +150 -0
- package/dist/core/auth/session.mjs.map +1 -0
- package/dist/core/auth/types.d.cts +55 -0
- package/dist/core/auth/types.d.cts.map +1 -0
- package/dist/core/auth/types.d.mts +55 -0
- package/dist/core/auth/types.d.mts.map +1 -0
- package/dist/core/auth/utils/encode.cjs +27 -0
- package/dist/core/auth/utils/encode.d.cts +15 -0
- package/dist/core/auth/utils/encode.d.cts.map +1 -0
- package/dist/core/auth/utils/encode.d.mts +15 -0
- package/dist/core/auth/utils/encode.d.mts.map +1 -0
- package/dist/core/auth/utils/encode.mjs +26 -0
- package/dist/core/auth/utils/encode.mjs.map +1 -0
- package/dist/core/auth/utils/encryption.cjs +67 -0
- package/dist/core/auth/utils/encryption.d.cts +28 -0
- package/dist/core/auth/utils/encryption.d.cts.map +1 -0
- package/dist/core/auth/utils/encryption.d.mts +28 -0
- package/dist/core/auth/utils/encryption.d.mts.map +1 -0
- package/dist/core/auth/utils/encryption.mjs +64 -0
- package/dist/core/auth/utils/encryption.mjs.map +1 -0
- package/dist/core/auth/validation.cjs +39 -0
- package/dist/core/auth/validation.d.cts +48 -0
- package/dist/core/auth/validation.d.cts.map +1 -0
- package/dist/core/auth/validation.d.mts +48 -0
- package/dist/core/auth/validation.d.mts.map +1 -0
- package/dist/core/auth/validation.mjs +31 -0
- package/dist/core/auth/validation.mjs.map +1 -0
- package/dist/core/bootstrap.cjs +32 -0
- package/dist/core/bootstrap.d.cts +5 -0
- package/dist/core/bootstrap.d.cts.map +1 -0
- package/dist/core/bootstrap.d.mts +5 -0
- package/dist/core/bootstrap.d.mts.map +1 -0
- package/dist/core/bootstrap.mjs +33 -0
- package/dist/core/bootstrap.mjs.map +1 -0
- package/dist/core/config.cjs +6 -0
- package/dist/core/config.d.cts +11 -0
- package/dist/core/config.d.cts.map +1 -0
- package/dist/core/config.d.mts +11 -0
- package/dist/core/config.d.mts.map +1 -0
- package/dist/core/config.mjs +6 -0
- package/dist/core/config.mjs.map +1 -0
- package/dist/core/config.server.cjs +60 -0
- package/dist/core/config.server.d.cts +16 -0
- package/dist/core/config.server.d.cts.map +1 -0
- package/dist/core/config.server.d.mts +16 -0
- package/dist/core/config.server.d.mts.map +1 -0
- package/dist/core/config.server.mjs +57 -0
- package/dist/core/config.server.mjs.map +1 -0
- package/dist/core/event-bus.cjs +48 -0
- package/dist/core/event-bus.d.cts +17 -0
- package/dist/core/event-bus.d.cts.map +1 -0
- package/dist/core/event-bus.d.mts +17 -0
- package/dist/core/event-bus.d.mts.map +1 -0
- package/dist/core/event-bus.mjs +48 -0
- package/dist/core/event-bus.mjs.map +1 -0
- package/dist/core/filesystem/service.cjs +43 -0
- package/dist/core/filesystem/service.d.cts +19 -0
- package/dist/core/filesystem/service.d.cts.map +1 -0
- package/dist/core/filesystem/service.d.mts +19 -0
- package/dist/core/filesystem/service.d.mts.map +1 -0
- package/dist/core/filesystem/service.mjs +43 -0
- package/dist/core/filesystem/service.mjs.map +1 -0
- package/dist/core/filesystem/types.d.cts +22 -0
- package/dist/core/filesystem/types.d.cts.map +1 -0
- package/dist/core/filesystem/types.d.mts +22 -0
- package/dist/core/filesystem/types.d.mts.map +1 -0
- package/dist/core/notifications/actions.cjs +36 -0
- package/dist/core/notifications/actions.d.cts +58 -0
- package/dist/core/notifications/actions.d.cts.map +1 -0
- package/dist/core/notifications/actions.d.mts +58 -0
- package/dist/core/notifications/actions.d.mts.map +1 -0
- package/dist/core/notifications/actions.mjs +33 -0
- package/dist/core/notifications/actions.mjs.map +1 -0
- package/dist/core/notifications/index.cjs +2 -0
- package/dist/core/notifications/index.mjs +4 -0
- package/dist/core/notifications/service.cjs +30 -0
- package/dist/core/notifications/service.d.cts +9 -0
- package/dist/core/notifications/service.d.cts.map +1 -0
- package/dist/core/notifications/service.d.mts +9 -0
- package/dist/core/notifications/service.d.mts.map +1 -0
- package/dist/core/notifications/service.mjs +31 -0
- package/dist/core/notifications/service.mjs.map +1 -0
- package/dist/core/notifications/types.d.cts +21 -0
- package/dist/core/notifications/types.d.cts.map +1 -0
- package/dist/core/notifications/types.d.mts +21 -0
- package/dist/core/notifications/types.d.mts.map +1 -0
- package/dist/core/setup.cjs +25 -0
- package/dist/core/setup.d.cts +9 -0
- package/dist/core/setup.d.cts.map +1 -0
- package/dist/core/setup.d.mts +9 -0
- package/dist/core/setup.d.mts.map +1 -0
- package/dist/core/setup.mjs +25 -0
- package/dist/core/setup.mjs.map +1 -0
- package/dist/core/types.d.cts +13 -0
- package/dist/core/types.d.cts.map +1 -0
- package/dist/core/types.d.mts +13 -0
- package/dist/core/types.d.mts.map +1 -0
- package/dist/index.cjs +30 -0
- package/dist/index.d.cts +8 -0
- package/dist/index.d.mts +8 -0
- package/dist/index.mjs +6 -0
- package/dist/server/auth/email.cjs +24 -0
- package/dist/server/auth/email.d.cts +13 -0
- package/dist/server/auth/email.d.cts.map +1 -0
- package/dist/server/auth/email.d.mts +13 -0
- package/dist/server/auth/email.d.mts.map +1 -0
- package/dist/server/auth/email.mjs +23 -0
- package/dist/server/auth/email.mjs.map +1 -0
- package/dist/server/auth/password.cjs +37 -0
- package/dist/server/auth/password.d.cts +23 -0
- package/dist/server/auth/password.d.cts.map +1 -0
- package/dist/server/auth/password.d.mts +23 -0
- package/dist/server/auth/password.d.mts.map +1 -0
- package/dist/server/auth/password.mjs +34 -0
- package/dist/server/auth/password.mjs.map +1 -0
- package/dist/server/auth/user.cjs +165 -0
- package/dist/server/auth/user.d.cts +58 -0
- package/dist/server/auth/user.d.cts.map +1 -0
- package/dist/server/auth/user.d.mts +58 -0
- package/dist/server/auth/user.d.mts.map +1 -0
- package/dist/server/auth/user.mjs +153 -0
- package/dist/server/auth/user.mjs.map +1 -0
- package/dist/server/database/inject.cjs +24 -0
- package/dist/server/database/inject.d.cts +15 -0
- package/dist/server/database/inject.d.cts.map +1 -0
- package/dist/server/database/inject.d.mts +15 -0
- package/dist/server/database/inject.d.mts.map +1 -0
- package/dist/server/database/inject.mjs +23 -0
- package/dist/server/database/inject.mjs.map +1 -0
- package/dist/server/database/schema.cjs +163 -0
- package/dist/server/database/schema.d.cts +2962 -0
- package/dist/server/database/schema.d.cts.map +1 -0
- package/dist/server/database/schema.d.mts +2962 -0
- package/dist/server/database/schema.d.mts.map +1 -0
- package/dist/server/database/schema.mjs +151 -0
- package/dist/server/database/schema.mjs.map +1 -0
- package/dist/server/emails/index.cjs +32 -0
- package/dist/server/emails/index.d.cts +26 -0
- package/dist/server/emails/index.d.cts.map +1 -0
- package/dist/server/emails/index.d.mts +26 -0
- package/dist/server/emails/index.d.mts.map +1 -0
- package/dist/server/emails/index.mjs +29 -0
- package/dist/server/emails/index.mjs.map +1 -0
- package/dist/server.cjs +145 -0
- package/dist/server.d.cts +26 -0
- package/dist/server.d.mts +26 -0
- package/dist/server.mjs +23 -0
- package/package.json +60 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logic.mjs","names":[],"sources":["../../../src/core/auth/logic.ts"],"sourcesContent":["\"use server\";\n\nimport { eq, inArray } from \"drizzle-orm\";\nimport {\n verifyPasswordHash,\n verifyPasswordStrength,\n} from \"../../server/auth/password\";\nimport {\n createUser,\n getUserById,\n getUserFromEmail,\n getUserPasswordHash,\n verifyUsernameInput,\n} from \"../../server/auth/user\";\nimport { db } from \"../../server/database/inject\";\nimport {\n permissionsTable,\n rolesTable,\n rolesToPermissionsTable,\n usersToPermissionsTable,\n usersToRolesTable,\n} from \"../../server/database/schema\";\nimport { eventBus } from \"../event-bus\";\nimport {\n augmentSession,\n augmentUser,\n registerIdentityAugmenter,\n registerPasswordResetSessionAugmenter,\n registerSessionAugmenter,\n} from \"./augment\";\nimport {\n createEmailVerificationRequest,\n sendVerificationEmail,\n setEmailVerificationRequestCookie,\n} from \"./email-verification\";\nimport {\n createSession,\n deleteSessionTokenCookie,\n generateSessionToken,\n getCurrentSession,\n invalidateSession,\n setSessionTokenCookie,\n} from \"./session\";\nimport type {\n AuthResponse,\n FullUser,\n Session,\n SessionFlags,\n User,\n UserPermission,\n UserRole,\n} from \"./types\";\nimport {\n type LoginInput,\n loginSchema,\n type RegisterInput,\n registerSchema,\n} from \"./validation\";\n\n/**\n * Podstawowy moduł rozszerzający tożsamość dla ról i uprawnień\n */\nasync function coreRbacAugmenter(user: User): Promise<Record<string, any>> {\n try {\n // 1. Fetch direct roles\n const userRoles = await db\n .select({ name: rolesTable.name })\n .from(usersToRolesTable)\n .innerJoin(rolesTable, eq(usersToRolesTable.roleId, rolesTable.id))\n .where(eq(usersToRolesTable.userId, user.id));\n\n const roles = userRoles.map((r) => r.name);\n\n // 2. Fetch direct permissions\n const userDirectPerms = await db\n .select({ name: permissionsTable.name })\n .from(usersToPermissionsTable)\n .innerJoin(\n permissionsTable,\n eq(usersToPermissionsTable.permissionId, permissionsTable.id),\n )\n .where(eq(usersToPermissionsTable.userId, user.id));\n\n const directPerms = userDirectPerms.map((p) => p.name);\n\n // 3. Fetch permissions from roles\n let rolePerms: string[] = [];\n if (roles.length > 0) {\n const roleIdsResult = await db\n .select({ id: rolesTable.id })\n .from(rolesTable)\n .where(inArray(rolesTable.name, roles));\n\n const roleIds = roleIdsResult.map((r) => r.id);\n\n if (roleIds.length > 0) {\n const rolePermsData = await db\n .select({ name: permissionsTable.name })\n .from(rolesToPermissionsTable)\n .innerJoin(\n permissionsTable,\n eq(rolesToPermissionsTable.permissionId, permissionsTable.id),\n )\n .where(inArray(rolesToPermissionsTable.roleId, roleIds));\n rolePerms = rolePermsData.map((p) => p.name);\n }\n }\n\n return {\n roles,\n permissions: Array.from(new Set([...directPerms, ...rolePerms])),\n };\n } catch (error) {\n console.error(\"[Auth:RBAC] Failed to augment user:\", error);\n return { roles: [], permissions: [] };\n }\n}\n\n/**\n * Registry for login validators (e.g. 2FA module)\n */\ntype AuthValidator = (userId: string) => Promise<AuthResponse | null>;\n\n/**\n * Registry for Security Requirements (e.g. checking if 2FA is needed for a session)\n */\ntype SecurityRequirement = (\n session: Session,\n user: FullUser,\n) => Promise<{ satisfied: boolean; redirect?: string } | null>;\n\n/**\n * Registry for password reset validators (e.g. 2FA module requiring check during reset)\n */\ntype PasswordResetValidator = (userId: string) => Promise<AuthResponse | null>;\n\n/**\n * Registry for email verification validators\n */\ntype EmailVerificationValidator = (\n userId: string,\n) => Promise<AuthResponse | null>;\n\nconst globalForAuth = globalThis as unknown as {\n __WINKLY_AUTH_VALIDATORS__: Set<AuthValidator> | undefined;\n __WINKLY_SECURITY_REQUIREMENTS__: Set<SecurityRequirement> | undefined;\n __WINKLY_PASSWORD_RESET_VALIDATORS__: Set<PasswordResetValidator> | undefined;\n __WINKLY_EMAIL_VERIFICATION_VALIDATORS__:\n | Set<EmailVerificationValidator>\n | undefined;\n};\n\nconst authValidators =\n globalForAuth.__WINKLY_AUTH_VALIDATORS__ ?? new Set<AuthValidator>();\nconst securityRequirements =\n globalForAuth.__WINKLY_SECURITY_REQUIREMENTS__ ??\n new Set<SecurityRequirement>();\nconst passwordResetValidators =\n globalForAuth.__WINKLY_PASSWORD_RESET_VALIDATORS__ ??\n new Set<PasswordResetValidator>();\nconst emailVerificationValidators =\n globalForAuth.__WINKLY_EMAIL_VERIFICATION_VALIDATORS__ ??\n new Set<EmailVerificationValidator>();\n\nglobalForAuth.__WINKLY_AUTH_VALIDATORS__ = authValidators;\nglobalForAuth.__WINKLY_SECURITY_REQUIREMENTS__ = securityRequirements;\nglobalForAuth.__WINKLY_PASSWORD_RESET_VALIDATORS__ = passwordResetValidators;\nglobalForAuth.__WINKLY_EMAIL_VERIFICATION_VALIDATORS__ =\n emailVerificationValidators;\n\nexport async function registerAuthValidator(validator: AuthValidator) {\n authValidators.add(validator);\n}\n\nexport async function registerPasswordResetValidator(\n validator: PasswordResetValidator,\n) {\n passwordResetValidators.add(validator);\n}\n\nexport async function registerEmailVerificationValidator(\n validator: EmailVerificationValidator,\n) {\n emailVerificationValidators.add(validator);\n}\n\nexport {\n registerIdentityAugmenter,\n registerSessionAugmenter,\n registerPasswordResetSessionAugmenter,\n augmentUser,\n augmentSession,\n};\n\nexport async function registerSecurityRequirement(\n requirement: SecurityRequirement,\n) {\n securityRequirements.add(requirement);\n}\n\nexport async function runPasswordResetValidators(\n userId: string,\n): Promise<AuthResponse | null> {\n for (const validator of passwordResetValidators) {\n const interception = await validator(userId);\n if (interception) return interception;\n }\n return null;\n}\n\nexport async function runEmailVerificationValidators(\n userId: string,\n): Promise<AuthResponse | null> {\n for (const validator of emailVerificationValidators) {\n const interception = await validator(userId);\n if (interception) return interception;\n }\n return null;\n}\n\n/**\n * Augments a base user with data from all registered modules.\n * This is now just a wrapper that includes core RBAC data.\n */\nexport async function performFullUserAugmentation(\n user: User,\n): Promise<FullUser> {\n const coreRbacData = await coreRbacAugmenter(user);\n return await augmentUser(user, coreRbacData);\n}\n\n/**\n * Checks if the current session satisfies all registered security requirements.\n */\nexport async function checkSecurity(\n session: Session,\n user: FullUser,\n requiredRoles?: UserRole[],\n requiredPermissions?: UserPermission[],\n fallbackRedirect?: string,\n) {\n if (!user) {\n console.warn(\"User is required for security check\");\n return { satisfied: false, redirect: fallbackRedirect ?? \"/signin\" };\n }\n\n const userRoles = Array.isArray(user.roles) ? user.roles : [];\n const userPermissions = Array.isArray(user.permissions)\n ? user.permissions\n : [];\n\n // 1. Core Role Check (At least one role must match)\n if (requiredRoles && requiredRoles.length > 0) {\n const hasRole = requiredRoles.some((role) => userRoles.includes(role));\n if (!hasRole) {\n console.warn(`User lacks required roles: ${requiredRoles.join(\", \")}`);\n return {\n satisfied: false,\n redirect: fallbackRedirect,\n };\n }\n }\n\n // 2. Core Permission Check (ALL permissions must match)\n if (requiredPermissions && requiredPermissions.length > 0) {\n const hasAllPermissions = requiredPermissions.every((perm) =>\n userPermissions.includes(perm),\n );\n if (!hasAllPermissions) {\n console.warn(\n `User lacks required permissions: ${requiredPermissions.join(\", \")}`,\n );\n\n return {\n satisfied: false,\n redirect: fallbackRedirect,\n };\n }\n }\n\n // 3. Modular Requirements Check\n if (securityRequirements) {\n for (const requirement of securityRequirements) {\n try {\n const result = await requirement(session, user);\n if (result && !result.satisfied) {\n return {\n ...result,\n redirect: result.redirect ?? fallbackRedirect,\n };\n }\n } catch (error) {\n console.error(\"[Auth:Security] Requirement failed:\", error);\n }\n }\n }\n return { satisfied: true };\n}\n\n/**\n * Sign In Logic\n */\nexport async function signIn(data: LoginInput): Promise<AuthResponse> {\n const { email, password } = await loginSchema.parseAsync(data);\n\n const user = await getUserFromEmail(email);\n if (!user) {\n return { status: \"ERROR\", message: \"Invalid email or password\" };\n }\n\n const passwordHash = await getUserPasswordHash(user.id);\n if (!passwordHash || !(await verifyPasswordHash(passwordHash, password))) {\n return { status: \"ERROR\", message: \"Invalid email or password\" };\n }\n\n // Interception Layer\n for (const validator of authValidators) {\n const interception = await validator(user.id);\n if (interception) return interception;\n }\n\n const sessionFlags: SessionFlags = {};\n const sessionToken = await generateSessionToken();\n const session = await createSession(sessionToken, user.id, sessionFlags);\n await setSessionTokenCookie(sessionToken, session.expiresAt);\n\n const fullUser = await performFullUserAugmentation(user);\n await eventBus.publish(\"auth:session-created\", { session, user: fullUser });\n\n return {\n status: \"SUCCESS\",\n session: { ...session },\n user: { ...fullUser },\n };\n}\n\n/**\n * Sign Up Logic\n */\nexport async function signUp(data: RegisterInput) {\n const { email, username, password } = registerSchema.parse(data);\n\n if (!(await verifyUsernameInput(username))) {\n throw new Error(\"Invalid username\");\n }\n\n if (!(await verifyPasswordStrength(password))) {\n throw new Error(\"Weak password\");\n }\n\n const user = await createUser(email, username, password);\n const verificationRequest = await createEmailVerificationRequest(\n user.id,\n user.email,\n );\n\n await sendVerificationEmail(\n verificationRequest.email,\n verificationRequest.code,\n );\n await setEmailVerificationRequestCookie(verificationRequest);\n\n const sessionFlags: SessionFlags = {};\n const sessionToken = await generateSessionToken();\n const session = await createSession(sessionToken, user.id, sessionFlags);\n await setSessionTokenCookie(sessionToken, session.expiresAt);\n\n const fullUser = await performFullUserAugmentation(user);\n await eventBus.publish(\"auth:session-created\", { session, user: fullUser });\n\n return {\n session: { ...session },\n user: { ...fullUser },\n };\n}\n\n/**\n * Finalizes login after a challenge\n */\nexport async function finalizeLogin(userId: string, flags: SessionFlags) {\n const sessionToken = await generateSessionToken();\n const session = await createSession(sessionToken, userId, flags);\n await setSessionTokenCookie(sessionToken, session.expiresAt);\n\n const user = await getUserById(userId);\n\n if (user) {\n await eventBus.publish(\"auth:session-created\", { session, user });\n }\n\n return {\n session: session ? { ...session } : null,\n user: user ? { ...user } : null,\n };\n}\n\n/**\n * Sign Out\n */\nexport async function signOut() {\n const { session, user } = await getCurrentSession();\n if (session) {\n if (user) {\n await eventBus.publish(\"auth:signed-out\", { userId: user.id });\n }\n await invalidateSession(session.id);\n await deleteSessionTokenCookie();\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
4
|
+
const require_inject = require('../../server/database/inject.cjs');
|
|
5
|
+
const require_schema = require('../../server/database/schema.cjs');
|
|
6
|
+
const require_index = require('../../server/emails/index.cjs');
|
|
7
|
+
const require_encode = require('./utils/encode.cjs');
|
|
8
|
+
const require_augment = require('./augment.cjs');
|
|
9
|
+
const require_logic = require('./logic.cjs');
|
|
10
|
+
let drizzle_orm = require("drizzle-orm");
|
|
11
|
+
let _oslojs_crypto_sha2 = require("@oslojs/crypto/sha2");
|
|
12
|
+
let _oslojs_encoding = require("@oslojs/encoding");
|
|
13
|
+
let date_fns = require("date-fns");
|
|
14
|
+
let next_headers = require("next/headers");
|
|
15
|
+
|
|
16
|
+
//#region src/core/auth/password-reset.ts
|
|
17
|
+
/**
|
|
18
|
+
* Creates a new password reset session.
|
|
19
|
+
*/
|
|
20
|
+
async function createPasswordResetSession(token, userId, email) {
|
|
21
|
+
const sessionId = (0, _oslojs_encoding.encodeHexLowerCase)((0, _oslojs_crypto_sha2.sha256)(new TextEncoder().encode(token)));
|
|
22
|
+
const [session] = await require_inject.db.insert(require_schema.passwordResetSessionTable).values({
|
|
23
|
+
id: sessionId,
|
|
24
|
+
email,
|
|
25
|
+
code: require_encode.generateRandomOTP(),
|
|
26
|
+
expiresAt: new Date((0, date_fns.addHours)(/* @__PURE__ */ new Date(), 1)),
|
|
27
|
+
userId
|
|
28
|
+
}).returning();
|
|
29
|
+
return session;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Validates the password reset session token and retrieves user data.
|
|
33
|
+
* The user data is augmented by registered modules (e.g. 2FA).
|
|
34
|
+
*/
|
|
35
|
+
async function validatePasswordResetSessionToken(token) {
|
|
36
|
+
const sessionId = (0, _oslojs_encoding.encodeHexLowerCase)((0, _oslojs_crypto_sha2.sha256)(new TextEncoder().encode(token)));
|
|
37
|
+
const [row] = await require_inject.db.select({
|
|
38
|
+
session: require_schema.passwordResetSessionTable,
|
|
39
|
+
user: require_schema.userTable
|
|
40
|
+
}).from(require_schema.passwordResetSessionTable).innerJoin(require_schema.userTable, (0, drizzle_orm.eq)(require_schema.passwordResetSessionTable.userId, require_schema.userTable.id)).where((0, drizzle_orm.eq)(require_schema.passwordResetSessionTable.id, sessionId));
|
|
41
|
+
if (!row || !row.user) return {
|
|
42
|
+
session: null,
|
|
43
|
+
user: null
|
|
44
|
+
};
|
|
45
|
+
const { session: baseSession, user: baseUser } = row;
|
|
46
|
+
if (/* @__PURE__ */ new Date() > baseSession.expiresAt) {
|
|
47
|
+
await require_inject.db.delete(require_schema.passwordResetSessionTable).where((0, drizzle_orm.eq)(require_schema.passwordResetSessionTable.id, baseSession.id));
|
|
48
|
+
return {
|
|
49
|
+
session: null,
|
|
50
|
+
user: null
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const { password, recovery_code, ...safeUser } = baseUser;
|
|
54
|
+
const user = await require_logic.performFullUserAugmentation(safeUser);
|
|
55
|
+
return {
|
|
56
|
+
session: await require_augment.augmentPasswordResetSession(baseSession),
|
|
57
|
+
user
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Marks the password reset session as email verified.
|
|
62
|
+
*/
|
|
63
|
+
async function setPasswordResetSessionAsEmailVerified(sessionId) {
|
|
64
|
+
await require_inject.db.update(require_schema.passwordResetSessionTable).set({ emailVerified: true }).where((0, drizzle_orm.eq)(require_schema.passwordResetSessionTable.id, sessionId));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Invalidates all password reset sessions for a user.
|
|
68
|
+
*/
|
|
69
|
+
async function invalidateUserPasswordResetSessions(userId) {
|
|
70
|
+
await require_inject.db.delete(require_schema.passwordResetSessionTable).where((0, drizzle_orm.eq)(require_schema.passwordResetSessionTable.userId, userId));
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Validates the current password reset session from cookies.
|
|
74
|
+
*/
|
|
75
|
+
async function getCurrentPasswordResetSession() {
|
|
76
|
+
const token = (await (0, next_headers.cookies)()).get("password_reset_session")?.value ?? null;
|
|
77
|
+
if (token === null) return {
|
|
78
|
+
session: null,
|
|
79
|
+
user: null
|
|
80
|
+
};
|
|
81
|
+
const result = await validatePasswordResetSessionToken(token);
|
|
82
|
+
if (result.session === null) await deletePasswordResetSessionTokenCookie();
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Sets the password reset session token cookie.
|
|
87
|
+
*/
|
|
88
|
+
async function setPasswordResetSessionTokenCookie(token, expiresAt) {
|
|
89
|
+
(await (0, next_headers.cookies)()).set("password_reset_session", token, {
|
|
90
|
+
expires: expiresAt,
|
|
91
|
+
sameSite: "lax",
|
|
92
|
+
httpOnly: true,
|
|
93
|
+
path: "/",
|
|
94
|
+
secure: process.env.NODE_ENV === "production"
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Deletes the password reset session token cookie.
|
|
99
|
+
*/
|
|
100
|
+
async function deletePasswordResetSessionTokenCookie() {
|
|
101
|
+
(await (0, next_headers.cookies)()).delete("password_reset_session");
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Sends a password reset email with the OTP code.
|
|
105
|
+
*/
|
|
106
|
+
async function sendPasswordResetEmail(email, code) {
|
|
107
|
+
await /* @__PURE__ */ require_index.sendResetPassword(email, code);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
//#endregion
|
|
111
|
+
exports.createPasswordResetSession = createPasswordResetSession;
|
|
112
|
+
exports.deletePasswordResetSessionTokenCookie = deletePasswordResetSessionTokenCookie;
|
|
113
|
+
exports.getCurrentPasswordResetSession = getCurrentPasswordResetSession;
|
|
114
|
+
exports.invalidateUserPasswordResetSessions = invalidateUserPasswordResetSessions;
|
|
115
|
+
exports.sendPasswordResetEmail = sendPasswordResetEmail;
|
|
116
|
+
exports.setPasswordResetSessionAsEmailVerified = setPasswordResetSessionAsEmailVerified;
|
|
117
|
+
exports.setPasswordResetSessionTokenCookie = setPasswordResetSessionTokenCookie;
|
|
118
|
+
exports.validatePasswordResetSessionToken = validatePasswordResetSessionToken;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { PasswordResetAuthSession, PasswordResetSession } from "./types.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/core/auth/password-reset.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Creates a new password reset session.
|
|
6
|
+
*/
|
|
7
|
+
declare function createPasswordResetSession(token: string, userId: string, email: string): Promise<PasswordResetSession>;
|
|
8
|
+
/**
|
|
9
|
+
* Validates the password reset session token and retrieves user data.
|
|
10
|
+
* The user data is augmented by registered modules (e.g. 2FA).
|
|
11
|
+
*/
|
|
12
|
+
declare function validatePasswordResetSessionToken(token: string): Promise<PasswordResetAuthSession>;
|
|
13
|
+
/**
|
|
14
|
+
* Marks the password reset session as email verified.
|
|
15
|
+
*/
|
|
16
|
+
declare function setPasswordResetSessionAsEmailVerified(sessionId: string): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Invalidates all password reset sessions for a user.
|
|
19
|
+
*/
|
|
20
|
+
declare function invalidateUserPasswordResetSessions(userId: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Validates the current password reset session from cookies.
|
|
23
|
+
*/
|
|
24
|
+
declare function getCurrentPasswordResetSession(): Promise<PasswordResetAuthSession>;
|
|
25
|
+
/**
|
|
26
|
+
* Sets the password reset session token cookie.
|
|
27
|
+
*/
|
|
28
|
+
declare function setPasswordResetSessionTokenCookie(token: string, expiresAt: Date): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Deletes the password reset session token cookie.
|
|
31
|
+
*/
|
|
32
|
+
declare function deletePasswordResetSessionTokenCookie(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Sends a password reset email with the OTP code.
|
|
35
|
+
*/
|
|
36
|
+
declare function sendPasswordResetEmail(email: string, code: string): Promise<void>;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { createPasswordResetSession, deletePasswordResetSessionTokenCookie, getCurrentPasswordResetSession, invalidateUserPasswordResetSessions, sendPasswordResetEmail, setPasswordResetSessionAsEmailVerified, setPasswordResetSessionTokenCookie, validatePasswordResetSessionToken };
|
|
39
|
+
//# sourceMappingURL=password-reset.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password-reset.d.cts","names":[],"sources":["../../../src/core/auth/password-reset.ts"],"mappings":";;;;;AAqBA;iBAAsB,0BAAA,CACpB,KAAA,UACA,MAAA,UACA,KAAA,WACC,OAAA,CAAQ,oBAAA;;;;;iBAqBW,iCAAA,CACpB,KAAA,WACC,OAAA,CAAQ,wBAAA;;;;iBAyCW,sCAAA,CACpB,SAAA,WACC,OAAA;AA7CH;;;AAAA,iBAyDsB,mCAAA,CACpB,MAAA,WACC,OAAA;;;;iBASmB,8BAAA,CAAA,GAAkC,OAAA,CAAQ,wBAAA;;AAzBhE;;iBA6CsB,kCAAA,CACpB,KAAA,UACA,SAAA,EAAW,IAAA,GACV,OAAA;;;AAlCH;iBAiDsB,qCAAA,CAAA,GAAyC,OAAA;;;;iBAQzC,sBAAA,CACpB,KAAA,UACA,IAAA,WACC,OAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { PasswordResetAuthSession, PasswordResetSession } from "./types.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/core/auth/password-reset.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Creates a new password reset session.
|
|
6
|
+
*/
|
|
7
|
+
declare function createPasswordResetSession(token: string, userId: string, email: string): Promise<PasswordResetSession>;
|
|
8
|
+
/**
|
|
9
|
+
* Validates the password reset session token and retrieves user data.
|
|
10
|
+
* The user data is augmented by registered modules (e.g. 2FA).
|
|
11
|
+
*/
|
|
12
|
+
declare function validatePasswordResetSessionToken(token: string): Promise<PasswordResetAuthSession>;
|
|
13
|
+
/**
|
|
14
|
+
* Marks the password reset session as email verified.
|
|
15
|
+
*/
|
|
16
|
+
declare function setPasswordResetSessionAsEmailVerified(sessionId: string): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Invalidates all password reset sessions for a user.
|
|
19
|
+
*/
|
|
20
|
+
declare function invalidateUserPasswordResetSessions(userId: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Validates the current password reset session from cookies.
|
|
23
|
+
*/
|
|
24
|
+
declare function getCurrentPasswordResetSession(): Promise<PasswordResetAuthSession>;
|
|
25
|
+
/**
|
|
26
|
+
* Sets the password reset session token cookie.
|
|
27
|
+
*/
|
|
28
|
+
declare function setPasswordResetSessionTokenCookie(token: string, expiresAt: Date): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Deletes the password reset session token cookie.
|
|
31
|
+
*/
|
|
32
|
+
declare function deletePasswordResetSessionTokenCookie(): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Sends a password reset email with the OTP code.
|
|
35
|
+
*/
|
|
36
|
+
declare function sendPasswordResetEmail(email: string, code: string): Promise<void>;
|
|
37
|
+
//#endregion
|
|
38
|
+
export { createPasswordResetSession, deletePasswordResetSessionTokenCookie, getCurrentPasswordResetSession, invalidateUserPasswordResetSessions, sendPasswordResetEmail, setPasswordResetSessionAsEmailVerified, setPasswordResetSessionTokenCookie, validatePasswordResetSessionToken };
|
|
39
|
+
//# sourceMappingURL=password-reset.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password-reset.d.mts","names":[],"sources":["../../../src/core/auth/password-reset.ts"],"mappings":";;;;;AAqBA;iBAAsB,0BAAA,CACpB,KAAA,UACA,MAAA,UACA,KAAA,WACC,OAAA,CAAQ,oBAAA;;;;;iBAqBW,iCAAA,CACpB,KAAA,WACC,OAAA,CAAQ,wBAAA;;;;iBAyCW,sCAAA,CACpB,SAAA,WACC,OAAA;AA7CH;;;AAAA,iBAyDsB,mCAAA,CACpB,MAAA,WACC,OAAA;;;;iBASmB,8BAAA,CAAA,GAAkC,OAAA,CAAQ,wBAAA;;AAzBhE;;iBA6CsB,kCAAA,CACpB,KAAA,UACA,SAAA,EAAW,IAAA,GACV,OAAA;;;AAlCH;iBAiDsB,qCAAA,CAAA,GAAyC,OAAA;;;;iBAQzC,sBAAA,CACpB,KAAA,UACA,IAAA,WACC,OAAA"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
import { db } from "../../server/database/inject.mjs";
|
|
4
|
+
import { passwordResetSessionTable, userTable } from "../../server/database/schema.mjs";
|
|
5
|
+
import { sendResetPassword } from "../../server/emails/index.mjs";
|
|
6
|
+
import { generateRandomOTP } from "./utils/encode.mjs";
|
|
7
|
+
import { augmentPasswordResetSession } from "./augment.mjs";
|
|
8
|
+
import { performFullUserAugmentation } from "./logic.mjs";
|
|
9
|
+
import { eq } from "drizzle-orm";
|
|
10
|
+
import { sha256 } from "@oslojs/crypto/sha2";
|
|
11
|
+
import { encodeHexLowerCase } from "@oslojs/encoding";
|
|
12
|
+
import { addHours } from "date-fns";
|
|
13
|
+
import { cookies } from "next/headers";
|
|
14
|
+
|
|
15
|
+
//#region src/core/auth/password-reset.ts
|
|
16
|
+
/**
|
|
17
|
+
* Creates a new password reset session.
|
|
18
|
+
*/
|
|
19
|
+
async function createPasswordResetSession(token, userId, email) {
|
|
20
|
+
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
|
|
21
|
+
const [session] = await db.insert(passwordResetSessionTable).values({
|
|
22
|
+
id: sessionId,
|
|
23
|
+
email,
|
|
24
|
+
code: generateRandomOTP(),
|
|
25
|
+
expiresAt: new Date(addHours(/* @__PURE__ */ new Date(), 1)),
|
|
26
|
+
userId
|
|
27
|
+
}).returning();
|
|
28
|
+
return session;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Validates the password reset session token and retrieves user data.
|
|
32
|
+
* The user data is augmented by registered modules (e.g. 2FA).
|
|
33
|
+
*/
|
|
34
|
+
async function validatePasswordResetSessionToken(token) {
|
|
35
|
+
const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));
|
|
36
|
+
const [row] = await db.select({
|
|
37
|
+
session: passwordResetSessionTable,
|
|
38
|
+
user: userTable
|
|
39
|
+
}).from(passwordResetSessionTable).innerJoin(userTable, eq(passwordResetSessionTable.userId, userTable.id)).where(eq(passwordResetSessionTable.id, sessionId));
|
|
40
|
+
if (!row || !row.user) return {
|
|
41
|
+
session: null,
|
|
42
|
+
user: null
|
|
43
|
+
};
|
|
44
|
+
const { session: baseSession, user: baseUser } = row;
|
|
45
|
+
if (/* @__PURE__ */ new Date() > baseSession.expiresAt) {
|
|
46
|
+
await db.delete(passwordResetSessionTable).where(eq(passwordResetSessionTable.id, baseSession.id));
|
|
47
|
+
return {
|
|
48
|
+
session: null,
|
|
49
|
+
user: null
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const { password, recovery_code, ...safeUser } = baseUser;
|
|
53
|
+
const user = await performFullUserAugmentation(safeUser);
|
|
54
|
+
return {
|
|
55
|
+
session: await augmentPasswordResetSession(baseSession),
|
|
56
|
+
user
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Marks the password reset session as email verified.
|
|
61
|
+
*/
|
|
62
|
+
async function setPasswordResetSessionAsEmailVerified(sessionId) {
|
|
63
|
+
await db.update(passwordResetSessionTable).set({ emailVerified: true }).where(eq(passwordResetSessionTable.id, sessionId));
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Invalidates all password reset sessions for a user.
|
|
67
|
+
*/
|
|
68
|
+
async function invalidateUserPasswordResetSessions(userId) {
|
|
69
|
+
await db.delete(passwordResetSessionTable).where(eq(passwordResetSessionTable.userId, userId));
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Validates the current password reset session from cookies.
|
|
73
|
+
*/
|
|
74
|
+
async function getCurrentPasswordResetSession() {
|
|
75
|
+
const token = (await cookies()).get("password_reset_session")?.value ?? null;
|
|
76
|
+
if (token === null) return {
|
|
77
|
+
session: null,
|
|
78
|
+
user: null
|
|
79
|
+
};
|
|
80
|
+
const result = await validatePasswordResetSessionToken(token);
|
|
81
|
+
if (result.session === null) await deletePasswordResetSessionTokenCookie();
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Sets the password reset session token cookie.
|
|
86
|
+
*/
|
|
87
|
+
async function setPasswordResetSessionTokenCookie(token, expiresAt) {
|
|
88
|
+
(await cookies()).set("password_reset_session", token, {
|
|
89
|
+
expires: expiresAt,
|
|
90
|
+
sameSite: "lax",
|
|
91
|
+
httpOnly: true,
|
|
92
|
+
path: "/",
|
|
93
|
+
secure: process.env.NODE_ENV === "production"
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Deletes the password reset session token cookie.
|
|
98
|
+
*/
|
|
99
|
+
async function deletePasswordResetSessionTokenCookie() {
|
|
100
|
+
(await cookies()).delete("password_reset_session");
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Sends a password reset email with the OTP code.
|
|
104
|
+
*/
|
|
105
|
+
async function sendPasswordResetEmail(email, code) {
|
|
106
|
+
await /* @__PURE__ */ sendResetPassword(email, code);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
//#endregion
|
|
110
|
+
export { createPasswordResetSession, deletePasswordResetSessionTokenCookie, getCurrentPasswordResetSession, invalidateUserPasswordResetSessions, sendPasswordResetEmail, setPasswordResetSessionAsEmailVerified, setPasswordResetSessionTokenCookie, validatePasswordResetSessionToken };
|
|
111
|
+
//# sourceMappingURL=password-reset.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password-reset.mjs","names":[],"sources":["../../../src/core/auth/password-reset.ts"],"sourcesContent":["\"use server\";\n\nimport { sha256 } from \"@oslojs/crypto/sha2\";\nimport { encodeHexLowerCase } from \"@oslojs/encoding\";\nimport { addHours } from \"date-fns\";\nimport { eq } from \"drizzle-orm\";\nimport { cookies } from \"next/headers\";\nimport { db } from \"../../server/database/inject\";\nimport {\n passwordResetSessionTable,\n userTable,\n} from \"../../server/database/schema\";\nimport { sendResetPassword } from \"../../server/emails\";\nimport { augmentPasswordResetSession } from \"./augment\";\nimport { performFullUserAugmentation } from \"./logic\";\nimport type { PasswordResetAuthSession, PasswordResetSession } from \"./types\";\nimport { generateRandomOTP } from \"./utils/encode\";\n\n/**\n * Creates a new password reset session.\n */\nexport async function createPasswordResetSession(\n token: string,\n userId: string,\n email: string,\n): Promise<PasswordResetSession> {\n const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));\n\n const [session] = await db\n .insert(passwordResetSessionTable)\n .values({\n id: sessionId,\n email: email,\n code: generateRandomOTP(),\n expiresAt: new Date(addHours(new Date(), 1)),\n userId: userId,\n })\n .returning();\n\n return session;\n}\n\n/**\n * Validates the password reset session token and retrieves user data.\n * The user data is augmented by registered modules (e.g. 2FA).\n */\nexport async function validatePasswordResetSessionToken(\n token: string,\n): Promise<PasswordResetAuthSession> {\n const sessionId = encodeHexLowerCase(sha256(new TextEncoder().encode(token)));\n\n const [row] = await db\n .select({\n session: passwordResetSessionTable,\n user: userTable,\n })\n .from(passwordResetSessionTable)\n .innerJoin(userTable, eq(passwordResetSessionTable.userId, userTable.id))\n .where(eq(passwordResetSessionTable.id, sessionId));\n\n if (!row || !row.user) {\n return { session: null, user: null };\n }\n\n const { session: baseSession, user: baseUser } = row;\n\n // Check for expiration\n if (new Date() > baseSession.expiresAt) {\n await db\n .delete(passwordResetSessionTable)\n .where(eq(passwordResetSessionTable.id, baseSession.id));\n return { session: null, user: null };\n }\n\n // STRICTLY remove non-serializable and sensitive fields\n const { password, recovery_code, ...safeUser } = baseUser;\n\n // AUGMENT (EXTENSIBILITY POINTS)\n const user = await performFullUserAugmentation(safeUser as any);\n const session = await augmentPasswordResetSession(\n baseSession as PasswordResetSession,\n );\n\n return { session, user };\n}\n\n/**\n * Marks the password reset session as email verified.\n */\nexport async function setPasswordResetSessionAsEmailVerified(\n sessionId: string,\n): Promise<void> {\n await db\n .update(passwordResetSessionTable)\n .set({\n emailVerified: true,\n })\n .where(eq(passwordResetSessionTable.id, sessionId));\n}\n\n/**\n * Invalidates all password reset sessions for a user.\n */\nexport async function invalidateUserPasswordResetSessions(\n userId: string,\n): Promise<void> {\n await db\n .delete(passwordResetSessionTable)\n .where(eq(passwordResetSessionTable.userId, userId));\n}\n\n/**\n * Validates the current password reset session from cookies.\n */\nexport async function getCurrentPasswordResetSession(): Promise<PasswordResetAuthSession> {\n const cookieStore = await cookies();\n const token = cookieStore.get(\"password_reset_session\")?.value ?? null;\n\n if (token === null) {\n return { session: null, user: null };\n }\n\n const result = await validatePasswordResetSessionToken(token);\n\n if (result.session === null) {\n await deletePasswordResetSessionTokenCookie();\n }\n\n return result;\n}\n\n/**\n * Sets the password reset session token cookie.\n */\nexport async function setPasswordResetSessionTokenCookie(\n token: string,\n expiresAt: Date,\n): Promise<void> {\n const cookieStore = await cookies();\n\n cookieStore.set(\"password_reset_session\", token, {\n expires: expiresAt,\n sameSite: \"lax\",\n httpOnly: true,\n path: \"/\",\n secure: process.env.NODE_ENV === \"production\",\n });\n}\n\n/**\n * Deletes the password reset session token cookie.\n */\nexport async function deletePasswordResetSessionTokenCookie(): Promise<void> {\n const cookieStore = await cookies();\n cookieStore.delete(\"password_reset_session\");\n}\n\n/**\n * Sends a password reset email with the OTP code.\n */\nexport async function sendPasswordResetEmail(\n email: string,\n code: string,\n): Promise<void> {\n await sendResetPassword(email, code);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAqBA,eAAsB,2BACpB,OACA,QACA,OAC+B;CAC/B,MAAM,YAAY,mBAAmB,OAAO,IAAI,aAAa,CAAC,OAAO,MAAM,CAAC,CAAC;CAE7E,MAAM,CAAC,WAAW,MAAM,GACrB,OAAO,0BAA0B,CACjC,OAAO;EACN,IAAI;EACG;EACP,MAAM,mBAAmB;EACzB,WAAW,IAAI,KAAK,yBAAS,IAAI,MAAM,EAAE,EAAE,CAAC;EACpC;EACT,CAAC,CACD,WAAW;AAEd,QAAO;;;;;;AAOT,eAAsB,kCACpB,OACmC;CACnC,MAAM,YAAY,mBAAmB,OAAO,IAAI,aAAa,CAAC,OAAO,MAAM,CAAC,CAAC;CAE7E,MAAM,CAAC,OAAO,MAAM,GACjB,OAAO;EACN,SAAS;EACT,MAAM;EACP,CAAC,CACD,KAAK,0BAA0B,CAC/B,UAAU,WAAW,GAAG,0BAA0B,QAAQ,UAAU,GAAG,CAAC,CACxE,MAAM,GAAG,0BAA0B,IAAI,UAAU,CAAC;AAErD,KAAI,CAAC,OAAO,CAAC,IAAI,KACf,QAAO;EAAE,SAAS;EAAM,MAAM;EAAM;CAGtC,MAAM,EAAE,SAAS,aAAa,MAAM,aAAa;AAGjD,qBAAI,IAAI,MAAM,GAAG,YAAY,WAAW;AACtC,QAAM,GACH,OAAO,0BAA0B,CACjC,MAAM,GAAG,0BAA0B,IAAI,YAAY,GAAG,CAAC;AAC1D,SAAO;GAAE,SAAS;GAAM,MAAM;GAAM;;CAItC,MAAM,EAAE,UAAU,eAAe,GAAG,aAAa;CAGjD,MAAM,OAAO,MAAM,4BAA4B,SAAgB;AAK/D,QAAO;EAAE,SAJO,MAAM,4BACpB,YACD;EAEiB;EAAM;;;;;AAM1B,eAAsB,uCACpB,WACe;AACf,OAAM,GACH,OAAO,0BAA0B,CACjC,IAAI,EACH,eAAe,MAChB,CAAC,CACD,MAAM,GAAG,0BAA0B,IAAI,UAAU,CAAC;;;;;AAMvD,eAAsB,oCACpB,QACe;AACf,OAAM,GACH,OAAO,0BAA0B,CACjC,MAAM,GAAG,0BAA0B,QAAQ,OAAO,CAAC;;;;;AAMxD,eAAsB,iCAAoE;CAExF,MAAM,SADc,MAAM,SAAS,EACT,IAAI,yBAAyB,EAAE,SAAS;AAElE,KAAI,UAAU,KACZ,QAAO;EAAE,SAAS;EAAM,MAAM;EAAM;CAGtC,MAAM,SAAS,MAAM,kCAAkC,MAAM;AAE7D,KAAI,OAAO,YAAY,KACrB,OAAM,uCAAuC;AAG/C,QAAO;;;;;AAMT,eAAsB,mCACpB,OACA,WACe;AAGf,EAFoB,MAAM,SAAS,EAEvB,IAAI,0BAA0B,OAAO;EAC/C,SAAS;EACT,UAAU;EACV,UAAU;EACV,MAAM;EACN,QAAQ,QAAQ,IAAI,aAAa;EAClC,CAAC;;;;;AAMJ,eAAsB,wCAAuD;AAE3E,EADoB,MAAM,SAAS,EACvB,OAAO,yBAAyB;;;;;AAM9C,eAAsB,uBACpB,OACA,MACe;AACf,OAAM,kCAAkB,OAAO,KAAK"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use server";
|
|
2
|
+
|
|
3
|
+
const require_runtime = require('../../_virtual/_rolldown/runtime.cjs');
|
|
4
|
+
const require_inject = require('../../server/database/inject.cjs');
|
|
5
|
+
const require_schema = require('../../server/database/schema.cjs');
|
|
6
|
+
const require_service = require('../notifications/service.cjs');
|
|
7
|
+
require('../notifications/index.cjs');
|
|
8
|
+
let drizzle_orm = require("drizzle-orm");
|
|
9
|
+
|
|
10
|
+
//#region src/core/auth/rbac.ts
|
|
11
|
+
if (typeof window === "undefined") require_service.notificationService.init();
|
|
12
|
+
/**
|
|
13
|
+
* CORE RBAC LOGIC
|
|
14
|
+
* This file handles all database operations for Roles and Permissions.
|
|
15
|
+
*/
|
|
16
|
+
async function getRoles() {
|
|
17
|
+
return await require_inject.db.select().from(require_schema.rolesTable).orderBy(require_schema.rolesTable.name);
|
|
18
|
+
}
|
|
19
|
+
async function getRoleById(roleId) {
|
|
20
|
+
const [role] = await require_inject.db.select().from(require_schema.rolesTable).where((0, drizzle_orm.eq)(require_schema.rolesTable.id, roleId));
|
|
21
|
+
return role;
|
|
22
|
+
}
|
|
23
|
+
async function createRole(name, description) {
|
|
24
|
+
return await require_inject.db.insert(require_schema.rolesTable).values({
|
|
25
|
+
name,
|
|
26
|
+
description
|
|
27
|
+
}).returning();
|
|
28
|
+
}
|
|
29
|
+
async function deleteRole(roleId) {
|
|
30
|
+
return await require_inject.db.delete(require_schema.rolesTable).where((0, drizzle_orm.eq)(require_schema.rolesTable.id, roleId));
|
|
31
|
+
}
|
|
32
|
+
async function getPermissions() {
|
|
33
|
+
return await require_inject.db.select().from(require_schema.permissionsTable).orderBy(require_schema.permissionsTable.name);
|
|
34
|
+
}
|
|
35
|
+
async function createPermission(name, description) {
|
|
36
|
+
return await require_inject.db.insert(require_schema.permissionsTable).values({
|
|
37
|
+
name,
|
|
38
|
+
description
|
|
39
|
+
}).returning();
|
|
40
|
+
}
|
|
41
|
+
async function deletePermission(permissionId) {
|
|
42
|
+
return await require_inject.db.delete(require_schema.permissionsTable).where((0, drizzle_orm.eq)(require_schema.permissionsTable.id, permissionId));
|
|
43
|
+
}
|
|
44
|
+
async function getRolePermissions(roleId) {
|
|
45
|
+
return await require_inject.db.select({
|
|
46
|
+
id: require_schema.permissionsTable.id,
|
|
47
|
+
name: require_schema.permissionsTable.name
|
|
48
|
+
}).from(require_schema.rolesToPermissionsTable).innerJoin(require_schema.permissionsTable, (0, drizzle_orm.eq)(require_schema.rolesToPermissionsTable.permissionId, require_schema.permissionsTable.id)).where((0, drizzle_orm.eq)(require_schema.rolesToPermissionsTable.roleId, roleId));
|
|
49
|
+
}
|
|
50
|
+
async function assignPermissionToRole(roleId, permissionId) {
|
|
51
|
+
return await require_inject.db.insert(require_schema.rolesToPermissionsTable).values({
|
|
52
|
+
roleId,
|
|
53
|
+
permissionId
|
|
54
|
+
}).onConflictDoNothing();
|
|
55
|
+
}
|
|
56
|
+
async function revokePermissionFromRole(roleId, permissionId) {
|
|
57
|
+
return await require_inject.db.delete(require_schema.rolesToPermissionsTable).where((0, drizzle_orm.and)((0, drizzle_orm.eq)(require_schema.rolesToPermissionsTable.roleId, roleId), (0, drizzle_orm.eq)(require_schema.rolesToPermissionsTable.permissionId, permissionId)));
|
|
58
|
+
}
|
|
59
|
+
async function assignRoleToUser(userId, roleId) {
|
|
60
|
+
return await require_inject.db.insert(require_schema.usersToRolesTable).values({
|
|
61
|
+
userId,
|
|
62
|
+
roleId
|
|
63
|
+
}).onConflictDoNothing();
|
|
64
|
+
}
|
|
65
|
+
async function revokeRoleFromUser(userId, roleId) {
|
|
66
|
+
return await require_inject.db.delete(require_schema.usersToRolesTable).where((0, drizzle_orm.and)((0, drizzle_orm.eq)(require_schema.usersToRolesTable.userId, userId), (0, drizzle_orm.eq)(require_schema.usersToRolesTable.roleId, roleId)));
|
|
67
|
+
}
|
|
68
|
+
async function assignPermissionToUser(userId, permissionId) {
|
|
69
|
+
return await require_inject.db.insert(require_schema.usersToPermissionsTable).values({
|
|
70
|
+
userId,
|
|
71
|
+
permissionId
|
|
72
|
+
}).onConflictDoNothing();
|
|
73
|
+
}
|
|
74
|
+
async function revokePermissionFromUser(userId, permissionId) {
|
|
75
|
+
return await require_inject.db.delete(require_schema.usersToPermissionsTable).where((0, drizzle_orm.and)((0, drizzle_orm.eq)(require_schema.usersToPermissionsTable.userId, userId), (0, drizzle_orm.eq)(require_schema.usersToPermissionsTable.permissionId, permissionId)));
|
|
76
|
+
}
|
|
77
|
+
async function getUserRbacData(userId) {
|
|
78
|
+
const roles = await require_inject.db.select({
|
|
79
|
+
id: require_schema.rolesTable.id,
|
|
80
|
+
name: require_schema.rolesTable.name
|
|
81
|
+
}).from(require_schema.usersToRolesTable).innerJoin(require_schema.rolesTable, (0, drizzle_orm.eq)(require_schema.usersToRolesTable.roleId, require_schema.rolesTable.id)).where((0, drizzle_orm.eq)(require_schema.usersToRolesTable.userId, userId));
|
|
82
|
+
const directPermissions = await require_inject.db.select({
|
|
83
|
+
id: require_schema.permissionsTable.id,
|
|
84
|
+
name: require_schema.permissionsTable.name
|
|
85
|
+
}).from(require_schema.usersToPermissionsTable).innerJoin(require_schema.permissionsTable, (0, drizzle_orm.eq)(require_schema.usersToPermissionsTable.permissionId, require_schema.permissionsTable.id)).where((0, drizzle_orm.eq)(require_schema.usersToPermissionsTable.userId, userId));
|
|
86
|
+
let rolePermissions = [];
|
|
87
|
+
if (roles.length > 0) {
|
|
88
|
+
const roleIds = roles.map((r) => r.id);
|
|
89
|
+
rolePermissions = await require_inject.db.select({
|
|
90
|
+
id: require_schema.permissionsTable.id,
|
|
91
|
+
name: require_schema.permissionsTable.name
|
|
92
|
+
}).from(require_schema.rolesToPermissionsTable).innerJoin(require_schema.permissionsTable, (0, drizzle_orm.eq)(require_schema.rolesToPermissionsTable.permissionId, require_schema.permissionsTable.id)).where((0, drizzle_orm.inArray)(require_schema.rolesToPermissionsTable.roleId, roleIds));
|
|
93
|
+
}
|
|
94
|
+
const effectiveMap = /* @__PURE__ */ new Map();
|
|
95
|
+
for (const p of [...directPermissions, ...rolePermissions]) effectiveMap.set(p.id, p);
|
|
96
|
+
return {
|
|
97
|
+
roles,
|
|
98
|
+
directPermissions,
|
|
99
|
+
effectivePermissions: Array.from(effectiveMap.values())
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
exports.assignPermissionToRole = assignPermissionToRole;
|
|
105
|
+
exports.assignPermissionToUser = assignPermissionToUser;
|
|
106
|
+
exports.assignRoleToUser = assignRoleToUser;
|
|
107
|
+
exports.createPermission = createPermission;
|
|
108
|
+
exports.createRole = createRole;
|
|
109
|
+
exports.deletePermission = deletePermission;
|
|
110
|
+
exports.deleteRole = deleteRole;
|
|
111
|
+
exports.getPermissions = getPermissions;
|
|
112
|
+
exports.getRoleById = getRoleById;
|
|
113
|
+
exports.getRolePermissions = getRolePermissions;
|
|
114
|
+
exports.getRoles = getRoles;
|
|
115
|
+
exports.getUserRbacData = getUserRbacData;
|
|
116
|
+
exports.revokePermissionFromRole = revokePermissionFromRole;
|
|
117
|
+
exports.revokePermissionFromUser = revokePermissionFromUser;
|
|
118
|
+
exports.revokeRoleFromUser = revokeRoleFromUser;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as pg from "pg";
|
|
2
|
+
|
|
3
|
+
//#region src/core/auth/rbac.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* CORE RBAC LOGIC
|
|
6
|
+
* This file handles all database operations for Roles and Permissions.
|
|
7
|
+
*/
|
|
8
|
+
declare function getRoles(): Promise<{
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
description: string | null;
|
|
12
|
+
}[]>;
|
|
13
|
+
declare function getRoleById(roleId: string): Promise<{
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
description: string | null;
|
|
17
|
+
}>;
|
|
18
|
+
declare function createRole(name: string, description?: string): Promise<{
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
description: string | null;
|
|
22
|
+
}[]>;
|
|
23
|
+
declare function deleteRole(roleId: string): Promise<pg.QueryResult<never>>;
|
|
24
|
+
declare function getPermissions(): Promise<{
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
description: string | null;
|
|
28
|
+
}[]>;
|
|
29
|
+
declare function createPermission(name: string, description?: string): Promise<{
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
description: string | null;
|
|
33
|
+
}[]>;
|
|
34
|
+
declare function deletePermission(permissionId: string): Promise<pg.QueryResult<never>>;
|
|
35
|
+
declare function getRolePermissions(roleId: string): Promise<{
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
}[]>;
|
|
39
|
+
declare function assignPermissionToRole(roleId: string, permissionId: string): Promise<pg.QueryResult<never>>;
|
|
40
|
+
declare function revokePermissionFromRole(roleId: string, permissionId: string): Promise<pg.QueryResult<never>>;
|
|
41
|
+
declare function assignRoleToUser(userId: string, roleId: string): Promise<pg.QueryResult<never>>;
|
|
42
|
+
declare function revokeRoleFromUser(userId: string, roleId: string): Promise<pg.QueryResult<never>>;
|
|
43
|
+
declare function assignPermissionToUser(userId: string, permissionId: string): Promise<pg.QueryResult<never>>;
|
|
44
|
+
declare function revokePermissionFromUser(userId: string, permissionId: string): Promise<pg.QueryResult<never>>;
|
|
45
|
+
declare function getUserRbacData(userId: string): Promise<{
|
|
46
|
+
roles: {
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
}[];
|
|
50
|
+
directPermissions: {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
}[];
|
|
54
|
+
effectivePermissions: {
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
}[];
|
|
58
|
+
}>;
|
|
59
|
+
//#endregion
|
|
60
|
+
export { assignPermissionToRole, assignPermissionToUser, assignRoleToUser, createPermission, createRole, deletePermission, deleteRole, getPermissions, getRoleById, getRolePermissions, getRoles, getUserRbacData, revokePermissionFromRole, revokePermissionFromUser, revokeRoleFromUser };
|
|
61
|
+
//# sourceMappingURL=rbac.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rbac.d.cts","names":[],"sources":["../../../src/core/auth/rbac.ts"],"mappings":";;;;;;AAyBA;iBAAsB,QAAA,CAAA,GAAQ,OAAA;;;;;iBAIR,WAAA,CAAY,MAAA,WAAc,OAAA;;;;;iBAQ1B,UAAA,CAAW,IAAA,UAAc,WAAA,YAAoB,OAAA;;;;;iBAI7C,UAAA,CAAW,MAAA,WAAc,OAAA,CAAf,EAAA,CAAe,WAAA;AAAA,iBAMzB,cAAA,CAAA,GAAc,OAAA;;;;;iBAOd,gBAAA,CAAiB,IAAA,UAAc,WAAA,YAAoB,OAAA;;;;;iBAOnD,gBAAA,CAAiB,YAAA,WAAoB,OAAA,CAArB,EAAA,CAAqB,WAAA;AAAA,iBAQrC,kBAAA,CAAmB,MAAA,WAAc,OAAA;;;;iBAcjC,sBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFsB,EAAA,CAEtB,WAAA;AAAA,iBAQA,wBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFwB,EAAA,CAExB,WAAA;AAAA,iBAcA,gBAAA,CAAiB,MAAA,UAAgB,MAAA,WAAc,OAAA,CAA/B,EAAA,CAA+B,WAAA;AAAA,iBAO/C,kBAAA,CAAmB,MAAA,UAAgB,MAAA,WAAc,OAAA,CAA/B,EAAA,CAA+B,WAAA;AAAA,iBAWjD,sBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFsB,EAAA,CAEtB,WAAA;AAAA,iBAQA,wBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFwB,EAAA,CAExB,WAAA;AAAA,iBAYA,eAAA,CAAgB,MAAA,WAAc,OAAA"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as pg from "pg";
|
|
2
|
+
|
|
3
|
+
//#region src/core/auth/rbac.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* CORE RBAC LOGIC
|
|
6
|
+
* This file handles all database operations for Roles and Permissions.
|
|
7
|
+
*/
|
|
8
|
+
declare function getRoles(): Promise<{
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
description: string | null;
|
|
12
|
+
}[]>;
|
|
13
|
+
declare function getRoleById(roleId: string): Promise<{
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
description: string | null;
|
|
17
|
+
}>;
|
|
18
|
+
declare function createRole(name: string, description?: string): Promise<{
|
|
19
|
+
id: string;
|
|
20
|
+
name: string;
|
|
21
|
+
description: string | null;
|
|
22
|
+
}[]>;
|
|
23
|
+
declare function deleteRole(roleId: string): Promise<pg.QueryResult<never>>;
|
|
24
|
+
declare function getPermissions(): Promise<{
|
|
25
|
+
id: string;
|
|
26
|
+
name: string;
|
|
27
|
+
description: string | null;
|
|
28
|
+
}[]>;
|
|
29
|
+
declare function createPermission(name: string, description?: string): Promise<{
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
description: string | null;
|
|
33
|
+
}[]>;
|
|
34
|
+
declare function deletePermission(permissionId: string): Promise<pg.QueryResult<never>>;
|
|
35
|
+
declare function getRolePermissions(roleId: string): Promise<{
|
|
36
|
+
id: string;
|
|
37
|
+
name: string;
|
|
38
|
+
}[]>;
|
|
39
|
+
declare function assignPermissionToRole(roleId: string, permissionId: string): Promise<pg.QueryResult<never>>;
|
|
40
|
+
declare function revokePermissionFromRole(roleId: string, permissionId: string): Promise<pg.QueryResult<never>>;
|
|
41
|
+
declare function assignRoleToUser(userId: string, roleId: string): Promise<pg.QueryResult<never>>;
|
|
42
|
+
declare function revokeRoleFromUser(userId: string, roleId: string): Promise<pg.QueryResult<never>>;
|
|
43
|
+
declare function assignPermissionToUser(userId: string, permissionId: string): Promise<pg.QueryResult<never>>;
|
|
44
|
+
declare function revokePermissionFromUser(userId: string, permissionId: string): Promise<pg.QueryResult<never>>;
|
|
45
|
+
declare function getUserRbacData(userId: string): Promise<{
|
|
46
|
+
roles: {
|
|
47
|
+
id: string;
|
|
48
|
+
name: string;
|
|
49
|
+
}[];
|
|
50
|
+
directPermissions: {
|
|
51
|
+
id: string;
|
|
52
|
+
name: string;
|
|
53
|
+
}[];
|
|
54
|
+
effectivePermissions: {
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
}[];
|
|
58
|
+
}>;
|
|
59
|
+
//#endregion
|
|
60
|
+
export { assignPermissionToRole, assignPermissionToUser, assignRoleToUser, createPermission, createRole, deletePermission, deleteRole, getPermissions, getRoleById, getRolePermissions, getRoles, getUserRbacData, revokePermissionFromRole, revokePermissionFromUser, revokeRoleFromUser };
|
|
61
|
+
//# sourceMappingURL=rbac.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rbac.d.mts","names":[],"sources":["../../../src/core/auth/rbac.ts"],"mappings":";;;;;;AAyBA;iBAAsB,QAAA,CAAA,GAAQ,OAAA;;;;;iBAIR,WAAA,CAAY,MAAA,WAAc,OAAA;;;;;iBAQ1B,UAAA,CAAW,IAAA,UAAc,WAAA,YAAoB,OAAA;;;;;iBAI7C,UAAA,CAAW,MAAA,WAAc,OAAA,CAAf,EAAA,CAAe,WAAA;AAAA,iBAMzB,cAAA,CAAA,GAAc,OAAA;;;;;iBAOd,gBAAA,CAAiB,IAAA,UAAc,WAAA,YAAoB,OAAA;;;;;iBAOnD,gBAAA,CAAiB,YAAA,WAAoB,OAAA,CAArB,EAAA,CAAqB,WAAA;AAAA,iBAQrC,kBAAA,CAAmB,MAAA,WAAc,OAAA;;;;iBAcjC,sBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFsB,EAAA,CAEtB,WAAA;AAAA,iBAQA,wBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFwB,EAAA,CAExB,WAAA;AAAA,iBAcA,gBAAA,CAAiB,MAAA,UAAgB,MAAA,WAAc,OAAA,CAA/B,EAAA,CAA+B,WAAA;AAAA,iBAO/C,kBAAA,CAAmB,MAAA,UAAgB,MAAA,WAAc,OAAA,CAA/B,EAAA,CAA+B,WAAA;AAAA,iBAWjD,sBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFsB,EAAA,CAEtB,WAAA;AAAA,iBAQA,wBAAA,CACpB,MAAA,UACA,YAAA,WAAoB,OAAA,CAFwB,EAAA,CAExB,WAAA;AAAA,iBAYA,eAAA,CAAgB,MAAA,WAAc,OAAA"}
|