@veap/auth 0.0.0-stage → 0.1.1

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.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +167 -2
  3. package/dist/actions/auth.actions.d.ts +23 -0
  4. package/dist/actions/auth.actions.js +40 -0
  5. package/dist/actions/index.d.ts +1 -0
  6. package/dist/actions/index.js +1 -0
  7. package/dist/client/auth.context.d.ts +29 -0
  8. package/dist/client/auth.context.js +64 -0
  9. package/dist/client/index.d.ts +1 -0
  10. package/dist/client/index.js +1 -0
  11. package/dist/common/augment.d.ts +26 -0
  12. package/dist/common/augment.js +63 -0
  13. package/dist/common/context.d.ts +30 -0
  14. package/dist/common/context.js +36 -0
  15. package/dist/common/index.d.ts +7 -0
  16. package/dist/common/index.js +7 -0
  17. package/dist/common/logic.d.ts +64 -0
  18. package/dist/common/logic.js +133 -0
  19. package/dist/common/registry.d.ts +28 -0
  20. package/dist/common/registry.js +76 -0
  21. package/dist/common/routes.d.ts +3 -0
  22. package/dist/common/routes.js +2 -0
  23. package/dist/common/tokens.d.ts +10 -0
  24. package/dist/common/tokens.js +8 -0
  25. package/dist/common/types.d.ts +178 -0
  26. package/dist/common/types.js +9 -0
  27. package/dist/crypto/aes-cipher.d.ts +8 -0
  28. package/dist/crypto/aes-cipher.js +12 -0
  29. package/dist/crypto/bcrypt-hasher.d.ts +12 -0
  30. package/dist/crypto/bcrypt-hasher.js +37 -0
  31. package/dist/crypto/contracts.d.ts +36 -0
  32. package/dist/crypto/contracts.js +3 -0
  33. package/dist/crypto/encryption.d.ts +18 -0
  34. package/dist/crypto/encryption.js +69 -0
  35. package/dist/crypto/index.d.ts +6 -0
  36. package/dist/crypto/index.js +6 -0
  37. package/dist/crypto/password.d.ts +19 -0
  38. package/dist/crypto/password.js +27 -0
  39. package/dist/crypto/token-generator.d.ts +10 -0
  40. package/dist/crypto/token-generator.js +25 -0
  41. package/dist/index.d.ts +11 -0
  42. package/dist/index.js +11 -0
  43. package/dist/migrations/0001_create_auth_tables.d.ts +4 -0
  44. package/dist/migrations/0001_create_auth_tables.js +122 -0
  45. package/dist/migrations/index.d.ts +4 -0
  46. package/dist/migrations/index.js +7 -0
  47. package/dist/models/EmailVerification.d.ts +23 -0
  48. package/dist/models/EmailVerification.js +19 -0
  49. package/dist/models/PasswordResetSession.d.ts +25 -0
  50. package/dist/models/PasswordResetSession.js +21 -0
  51. package/dist/models/Permission.d.ts +20 -0
  52. package/dist/models/Permission.js +19 -0
  53. package/dist/models/Role.d.ts +20 -0
  54. package/dist/models/Role.js +19 -0
  55. package/dist/models/Session.d.ts +22 -0
  56. package/dist/models/Session.js +21 -0
  57. package/dist/models/User.d.ts +32 -0
  58. package/dist/models/User.js +31 -0
  59. package/dist/models/index.d.ts +6 -0
  60. package/dist/models/index.js +6 -0
  61. package/dist/models.d.ts +1 -0
  62. package/dist/models.js +1 -0
  63. package/dist/passwords/contracts.d.ts +28 -0
  64. package/dist/passwords/contracts.js +2 -0
  65. package/dist/passwords/index.d.ts +4 -0
  66. package/dist/passwords/index.js +4 -0
  67. package/dist/passwords/password-reset.facade.d.ts +14 -0
  68. package/dist/passwords/password-reset.facade.js +57 -0
  69. package/dist/passwords/password-reset.repository.d.ts +10 -0
  70. package/dist/passwords/password-reset.repository.js +39 -0
  71. package/dist/passwords/password-reset.service.d.ts +38 -0
  72. package/dist/passwords/password-reset.service.js +242 -0
  73. package/dist/providers/auth.provider.d.ts +9 -0
  74. package/dist/providers/auth.provider.js +199 -0
  75. package/dist/providers/index.d.ts +2 -0
  76. package/dist/providers/index.js +2 -0
  77. package/dist/providers/setup.d.ts +7 -0
  78. package/dist/providers/setup.js +29 -0
  79. package/dist/rbac/contracts.d.ts +75 -0
  80. package/dist/rbac/contracts.js +4 -0
  81. package/dist/rbac/index.d.ts +4 -0
  82. package/dist/rbac/index.js +4 -0
  83. package/dist/rbac/rbac.facade.d.ts +23 -0
  84. package/dist/rbac/rbac.facade.js +85 -0
  85. package/dist/rbac/rbac.repository.d.ts +30 -0
  86. package/dist/rbac/rbac.repository.js +137 -0
  87. package/dist/rbac/rbac.service.d.ts +35 -0
  88. package/dist/rbac/rbac.service.js +143 -0
  89. package/dist/server.d.ts +3 -0
  90. package/dist/server.js +3 -0
  91. package/dist/session/auth.service.d.ts +35 -0
  92. package/dist/session/auth.service.js +207 -0
  93. package/dist/session/contracts.d.ts +33 -0
  94. package/dist/session/contracts.js +2 -0
  95. package/dist/session/index.d.ts +5 -0
  96. package/dist/session/index.js +5 -0
  97. package/dist/session/session.facade.d.ts +14 -0
  98. package/dist/session/session.facade.js +75 -0
  99. package/dist/session/session.repository.d.ts +15 -0
  100. package/dist/session/session.repository.js +55 -0
  101. package/dist/session/session.service.d.ts +63 -0
  102. package/dist/session/session.service.js +221 -0
  103. package/dist/users/contracts.d.ts +33 -0
  104. package/dist/users/contracts.js +2 -0
  105. package/dist/users/index.d.ts +4 -0
  106. package/dist/users/index.js +4 -0
  107. package/dist/users/user.facade.d.ts +28 -0
  108. package/dist/users/user.facade.js +92 -0
  109. package/dist/users/user.repository.d.ts +16 -0
  110. package/dist/users/user.repository.js +60 -0
  111. package/dist/users/user.service.d.ts +80 -0
  112. package/dist/users/user.service.js +201 -0
  113. package/dist/validation/index.d.ts +90 -0
  114. package/dist/validation/index.js +46 -0
  115. package/dist/verification/contracts.d.ts +25 -0
  116. package/dist/verification/contracts.js +2 -0
  117. package/dist/verification/index.d.ts +4 -0
  118. package/dist/verification/index.js +4 -0
  119. package/dist/verification/verification.facade.d.ts +10 -0
  120. package/dist/verification/verification.facade.js +49 -0
  121. package/dist/verification/verification.repository.d.ts +7 -0
  122. package/dist/verification/verification.repository.js +23 -0
  123. package/dist/verification/verification.service.d.ts +44 -0
  124. package/dist/verification/verification.service.js +122 -0
  125. package/package.json +84 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Damian Miller
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,168 @@
1
- # Temporary Holding Version
1
+ [![CI](https://github.com/veapjs/veap-auth/actions/workflows/CI.yml/badge.svg)](https://github.com/veapjs/veap-auth/actions/workflows/CI.yml)
2
+ [![Release](https://github.com/veapjs/veap-auth/actions/workflows/RELEASE.yml/badge.svg)](https://github.com/veapjs/veap-auth/actions/workflows/RELEASE.yml)
3
+ [![Version](https://img.shields.io/npm/v/@veap/auth?style=flat&colorA=000000&colorB=000000)](https://www.npmjs.com/package/@veap/auth)
2
4
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
5
+ # @veap/auth
6
+
7
+ Production-ready authentication, session management, RBAC, and cryptographic
8
+ adapters for Veap and Next.js applications.
9
+
10
+ ## Overview
11
+
12
+ `@veap/auth` provides a modular authentication engine adhering to clean
13
+ architecture principles modeled after `@veap/kernel`. It decouples domain entities (users, sessions, roles,
14
+ permissions) and ports (hasher, token generator, cipher) into dedicated functional modules. It includes ready-to-use Next.js Server
15
+ Actions, automatic database migrations, and Active Record adapters powered by
16
+ `@veap/database`.
17
+
18
+ ## Architecture & Structure
19
+
20
+ Following the same modular, domain-driven structure as `@veap/kernel`:
21
+
22
+ ```text
23
+ src/
24
+ ├── actions/ # Next.js Server Actions (signIn, signUp, signOut, etc.)
25
+ ├── client/ # React hooks and context (useUser, AuthProvider)
26
+ ├── common/ # Common context, routes, registry, and augmentation
27
+ ├── crypto/ # Cryptography ports and adapters (bcrypt, AES, tokens)
28
+ ├── migrations/ # Database migration definitions
29
+ ├── models/ # ActiveRecord database models (User, Role, Session, etc.)
30
+ ├── passwords/ # Password reset repositories, service, and facades
31
+ ├── providers/ # AuthServiceProvider and bootstrap setup
32
+ ├── rbac/ # Role-based access control repositories, service, and facades
33
+ ├── session/ # Session repository, SessionService, and AuthService
34
+ ├── users/ # User repository, UserService, and facades
35
+ ├── validation/ # Zod input validation schemas
36
+ ├── index.ts # Main barrel entrypoint
37
+ ├── server.ts # Server-only utilities entrypoint
38
+ ├── client.tsx # React client entrypoint
39
+ ├── actions.ts # Server actions entrypoint
40
+ └── models.ts # ActiveRecord models entrypoint
41
+ ```
42
+
43
+ ## Features
44
+
45
+ - **Multi-layer authentication**: Secure password hashing with bcrypt, session
46
+ token generation via `@oslojs/crypto`, and AES secret encryption.
47
+ - **Session management**: Database-backed session persistence with automatic
48
+ token hashing, TTL expiry, and sliding-window extension.
49
+ - **Role-Based Access Control (RBAC)**: Fine-grained roles and permissions
50
+ associated with users through many-to-many database relations.
51
+ - **Next.js Server Actions**: First-class `signIn`, `signUp`, `signOut`, and
52
+ `getCurrentSession` actions returning typed `Result` objects.
53
+ - **Automated migrations**: Self-bootstrapping migrations for users, sessions,
54
+ roles, permissions, password reset requests, and email verification.
55
+ - **Client & React hooks**: Lightweight `useUser()` hook and `AuthProvider`
56
+ for responsive user sessions.
57
+
58
+ ## Installation
59
+
60
+ ```bash
61
+ # Using bun
62
+ bun add @veap/auth @veap/kernel @veap/database
63
+
64
+ # Using pnpm
65
+ pnpm add @veap/auth @veap/kernel @veap/database
66
+
67
+ # Using npm
68
+ npm install @veap/auth @veap/kernel @veap/database
69
+ ```
70
+
71
+ ## Usage
72
+
73
+ ### Register in Application Builder
74
+
75
+ Include `AuthServiceProvider` in your application composition root:
76
+
77
+ ```ts
78
+ import { Application } from "@veap/kernel";
79
+ import { DatabaseServiceProvider } from "@veap/database";
80
+ import { AuthServiceProvider } from "@veap/auth";
81
+
82
+ export const app = Application.configure()
83
+ .use(DatabaseServiceProvider)
84
+ .use(
85
+ new AuthServiceProvider(undefined, {
86
+ autoMigrate: true, // Automatically applies auth tables on boot
87
+ }),
88
+ )
89
+ .create();
90
+ ```
91
+
92
+ ### Sign In & Sign Out with Server Actions
93
+
94
+ Authenticate users in server components or server actions:
95
+
96
+ ```ts
97
+ "use server";
98
+
99
+ import { signIn, signOut, getCurrentSession } from "@veap/auth";
100
+
101
+ export async function handleLogin(formData: FormData) {
102
+ const email = formData.get("email") as string;
103
+ const password = formData.get("password") as string;
104
+
105
+ const result = await signIn({ email, password });
106
+
107
+ if (!result.success) {
108
+ return { error: result.error?.message || "Invalid credentials" };
109
+ }
110
+
111
+ return { user: result.data.user };
112
+ }
113
+
114
+ export async function handleLogout() {
115
+ await signOut();
116
+ }
117
+
118
+ export async function getActiveUser() {
119
+ const session = await getCurrentSession();
120
+ return session?.user ?? null;
121
+ }
122
+ ```
123
+
124
+ ### Querying Auth Models Directly
125
+
126
+ Interact with Active Record models provided by `@veap/auth/models`:
127
+
128
+ ```ts
129
+ import { User, Role } from "@veap/auth/models";
130
+ import { hashPassword } from "@veap/auth/server";
131
+
132
+ // Create a new user with hashed credentials
133
+ const user = await User.create({
134
+ name: "Jane Doe",
135
+ email: "jane@example.com",
136
+ password: await hashPassword("securePassword123"),
137
+ recovery_code: Buffer.from("recovery-key-bytes"),
138
+ });
139
+
140
+ // Check roles and permissions
141
+ const adminRole = await Role.query().where("name", "admin").first();
142
+ if (adminRole) {
143
+ await user.roles().attach(adminRole.id);
144
+ }
145
+ ```
146
+
147
+ ## Subpath Exports
148
+
149
+ | Export Path | Content |
150
+ | ----------------------- | --------------------------------------------------------------------- |
151
+ | `@veap/auth` | Core actions (`signIn`, `signOut`), provider, context, and schemas |
152
+ | `@veap/auth/client` | React client components, context, and `useUser` hook |
153
+ | `@veap/auth/server` | Server cryptographic utilities (`hashPassword`, `verifyPasswordHash`) |
154
+ | `@veap/auth/actions` | Next.js Server Actions directly exportable for actions boundaries |
155
+ | `@veap/auth/models` | Active Record models (`User`, `Session`, `Role`, `Permission`) |
156
+ | `@veap/auth/migrations` | Knex migrations for authentication tables |
157
+
158
+ ## Documentation
159
+
160
+ For full guides and authentication customization, visit:
161
+
162
+ - **Official Website**: [https://veap.pl](https://veap.pl)
163
+ - **Documentation**: [https://veap.pl/docs](https://veap.pl/docs)
164
+ - **GitHub Repository**: [https://github.com/veapjs/veap-auth](https://github.com/veapjs/veap-auth)
165
+
166
+ ## License
167
+
168
+ MIT
@@ -0,0 +1,23 @@
1
+ import { type Result } from "@veap/kernel";
2
+ import type { AuthResponse, SessionFlags } from "../common/index.js";
3
+ import type { LoginInput, RegisterInput } from "../validation/index.js";
4
+ export declare function signIn(data: LoginInput): Promise<Result<AuthResponse>>;
5
+ export declare function signUp(data: RegisterInput): Promise<{
6
+ success: false;
7
+ error: import("@veap/kernel").AppErrorJson;
8
+ data?: never;
9
+ } | {
10
+ success: true;
11
+ data: AuthResponse;
12
+ error?: never;
13
+ }>;
14
+ export declare function finalizeLogin(userId: string, flags: SessionFlags): Promise<{
15
+ success: false;
16
+ error: import("@veap/kernel").AppErrorJson;
17
+ data?: never;
18
+ } | {
19
+ success: true;
20
+ data: AuthResponse;
21
+ error?: never;
22
+ }>;
23
+ export declare function signOut(): Promise<Result<void>>;
@@ -0,0 +1,40 @@
1
+ "use server";
2
+ import { app, handleActionError, ok } from "@veap/kernel";
3
+ import { AuthService } from "../session/auth.service.js";
4
+ export async function signIn(data) {
5
+ try {
6
+ const authService = await app(AuthService);
7
+ return ok(await authService.signIn(data));
8
+ }
9
+ catch (e) {
10
+ return handleActionError(e, "Auth:SignIn");
11
+ }
12
+ }
13
+ export async function signUp(data) {
14
+ try {
15
+ const authService = await app(AuthService);
16
+ return ok(await authService.signUp(data));
17
+ }
18
+ catch (e) {
19
+ return handleActionError(e, "Auth:SignUp");
20
+ }
21
+ }
22
+ export async function finalizeLogin(userId, flags) {
23
+ try {
24
+ const authService = await app(AuthService);
25
+ return ok(await authService.finalizeLogin(userId, flags));
26
+ }
27
+ catch (e) {
28
+ return handleActionError(e, "Auth:FinalizeLogin");
29
+ }
30
+ }
31
+ export async function signOut() {
32
+ try {
33
+ const authService = await app(AuthService);
34
+ await authService.signOut();
35
+ return ok(undefined);
36
+ }
37
+ catch (e) {
38
+ return handleActionError(e, "Auth:SignOut");
39
+ }
40
+ }
@@ -0,0 +1 @@
1
+ export * from "./auth.actions.js";
@@ -0,0 +1 @@
1
+ export * from "./auth.actions.js";
@@ -0,0 +1,29 @@
1
+ import { type ReactNode } from "react";
2
+ import { type AuthRoutesConfig } from "../common/routes.js";
3
+ import type { AuthSession } from "../common/types.js";
4
+ export interface AuthContextValue {
5
+ user: AuthSession["user"] | null | undefined;
6
+ session: AuthSession["session"] | null | undefined;
7
+ prefix: string;
8
+ isLoading: boolean;
9
+ refetchUser: () => Promise<void>;
10
+ routes: AuthRoutesConfig;
11
+ }
12
+ export declare const AuthContext: import("react").Context<AuthContextValue | undefined>;
13
+ export declare const PathPrefixContext: import("react").Context<string>;
14
+ export interface AuthProviderProps {
15
+ children: ReactNode;
16
+ initialSession?: AuthSession | null;
17
+ prefix?: string;
18
+ routes?: AuthRoutesConfig;
19
+ }
20
+ export declare function AuthProvider({ children, initialSession, prefix, routes, }: AuthProviderProps): import("react").JSX.Element;
21
+ /**
22
+ * Hook to access configured authentication route URLs on the client.
23
+ */
24
+ export declare function useAuthRoutes(): AuthRoutesConfig;
25
+ /**
26
+ * Hook for user management on the client.
27
+ * @returns Returns an object with user data and functions for managing it.
28
+ */
29
+ export declare function useUser(): AuthContextValue;
@@ -0,0 +1,64 @@
1
+ "use client";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext, useEffect, useState, } from "react";
4
+ import { DEFAULT_AUTH_ROUTES, } from "../common/routes.js";
5
+ export const AuthContext = createContext(undefined);
6
+ export const PathPrefixContext = createContext("/app");
7
+ export function AuthProvider({ children, initialSession, prefix = "/app", routes = DEFAULT_AUTH_ROUTES, }) {
8
+ const [user, setUser] = useState(initialSession?.user ?? null);
9
+ const [session, setSession] = useState(initialSession?.session ?? null);
10
+ const [isLoading, setIsLoading] = useState(!initialSession);
11
+ const refetchUser = async () => {
12
+ try {
13
+ setIsLoading(true);
14
+ const res = await fetch("/api/auth/me", { credentials: "same-origin" });
15
+ if (res.ok) {
16
+ const data = await res.json();
17
+ setUser(data.user);
18
+ setSession(data.session);
19
+ }
20
+ else {
21
+ setUser(null);
22
+ setSession(null);
23
+ }
24
+ }
25
+ catch {
26
+ setUser(null);
27
+ setSession(null);
28
+ }
29
+ finally {
30
+ setIsLoading(false);
31
+ }
32
+ };
33
+ useEffect(() => {
34
+ if (!initialSession) {
35
+ refetchUser();
36
+ }
37
+ }, [initialSession]);
38
+ return (_jsx(AuthContext.Provider, { value: {
39
+ user,
40
+ session,
41
+ prefix,
42
+ isLoading,
43
+ refetchUser,
44
+ routes,
45
+ }, children: _jsx(PathPrefixContext.Provider, { value: prefix, children: children }) }));
46
+ }
47
+ /**
48
+ * Hook to access configured authentication route URLs on the client.
49
+ */
50
+ export function useAuthRoutes() {
51
+ const context = useContext(AuthContext);
52
+ return context?.routes ?? DEFAULT_AUTH_ROUTES;
53
+ }
54
+ /**
55
+ * Hook for user management on the client.
56
+ * @returns Returns an object with user data and functions for managing it.
57
+ */
58
+ export function useUser() {
59
+ const context = useContext(AuthContext);
60
+ if (!context) {
61
+ throw new Error("useUser must be used within AuthProvider");
62
+ }
63
+ return { ...context };
64
+ }
@@ -0,0 +1 @@
1
+ export * from "./auth.context.js";
@@ -0,0 +1 @@
1
+ export * from "./auth.context.js";
@@ -0,0 +1,26 @@
1
+ import { AuthCallbackRegistry } from "./registry.js";
2
+ import type { FullUser, PasswordResetSession, Session, User } from "./types.js";
3
+ /**
4
+ * REGISTRIES FOR MODULAR EXTENSIONS
5
+ */
6
+ export type IdentityAugmenter = (user: User) => Promise<Partial<FullUser>>;
7
+ export type SessionAugmenter = (session: Session) => Promise<Partial<Session>>;
8
+ export type PasswordResetSessionAugmenter = (session: PasswordResetSession) => Promise<Partial<PasswordResetSession>>;
9
+ export declare const identityAugmenters: AuthCallbackRegistry<IdentityAugmenter>;
10
+ export declare const sessionAugmenters: AuthCallbackRegistry<SessionAugmenter>;
11
+ export declare const passwordResetSessionAugmenters: AuthCallbackRegistry<PasswordResetSessionAugmenter>;
12
+ export declare function registerIdentityAugmenter(augmenter: IdentityAugmenter): void;
13
+ export declare function registerIdentityAugmenter(id: string, augmenter: IdentityAugmenter): void;
14
+ export declare function unregisterIdentityAugmenter(idOrAugmenter: string | IdentityAugmenter): boolean;
15
+ export declare function registerSessionAugmenter(augmenter: SessionAugmenter): void;
16
+ export declare function registerSessionAugmenter(id: string, augmenter: SessionAugmenter): void;
17
+ export declare function unregisterSessionAugmenter(idOrAugmenter: string | SessionAugmenter): boolean;
18
+ export declare function registerPasswordResetSessionAugmenter(augmenter: PasswordResetSessionAugmenter): void;
19
+ export declare function registerPasswordResetSessionAugmenter(id: string, augmenter: PasswordResetSessionAugmenter): void;
20
+ export declare function unregisterPasswordResetSessionAugmenter(idOrAugmenter: string | PasswordResetSessionAugmenter): boolean;
21
+ /**
22
+ * EXECUTION FUNCTIONS
23
+ */
24
+ export declare function augmentUser(user: User, coreRbacData?: Record<string, any>): Promise<FullUser>;
25
+ export declare function augmentSession(session: Session): Promise<Session>;
26
+ export declare function augmentPasswordResetSession(session: PasswordResetSession): Promise<PasswordResetSession>;
@@ -0,0 +1,63 @@
1
+ import { AuthCallbackRegistry } from "./registry.js";
2
+ const globalForAugment = globalThis;
3
+ export const identityAugmenters = globalForAugment.__VEAP_IDENTITY_AUGMENTERS__ ??
4
+ new AuthCallbackRegistry();
5
+ export const sessionAugmenters = globalForAugment.__VEAP_SESSION_AUGMENTERS__ ??
6
+ new AuthCallbackRegistry();
7
+ export const passwordResetSessionAugmenters = globalForAugment.__VEAP_PASSWORD_RESET_SESSION_AUGMENTERS__ ??
8
+ new AuthCallbackRegistry();
9
+ globalForAugment.__VEAP_IDENTITY_AUGMENTERS__ = identityAugmenters;
10
+ globalForAugment.__VEAP_SESSION_AUGMENTERS__ = sessionAugmenters;
11
+ globalForAugment.__VEAP_PASSWORD_RESET_SESSION_AUGMENTERS__ =
12
+ passwordResetSessionAugmenters;
13
+ export function registerIdentityAugmenter(idOrAugmenter, augmenter) {
14
+ identityAugmenters.register(idOrAugmenter, augmenter);
15
+ }
16
+ export function unregisterIdentityAugmenter(idOrAugmenter) {
17
+ return identityAugmenters.unregister(idOrAugmenter);
18
+ }
19
+ export function registerSessionAugmenter(idOrAugmenter, augmenter) {
20
+ sessionAugmenters.register(idOrAugmenter, augmenter);
21
+ }
22
+ export function unregisterSessionAugmenter(idOrAugmenter) {
23
+ return sessionAugmenters.unregister(idOrAugmenter);
24
+ }
25
+ export function registerPasswordResetSessionAugmenter(idOrAugmenter, augmenter) {
26
+ passwordResetSessionAugmenters.register(idOrAugmenter, augmenter);
27
+ }
28
+ export function unregisterPasswordResetSessionAugmenter(idOrAugmenter) {
29
+ return passwordResetSessionAugmenters.unregister(idOrAugmenter);
30
+ }
31
+ /**
32
+ * EXECUTION FUNCTIONS
33
+ */
34
+ export async function augmentUser(user, coreRbacData) {
35
+ let currentUser = { ...user, ...(coreRbacData || {}) };
36
+ for (const augmenter of identityAugmenters) {
37
+ const data = await augmenter(currentUser);
38
+ currentUser = { ...currentUser, ...data };
39
+ }
40
+ return currentUser;
41
+ }
42
+ export async function augmentSession(session) {
43
+ let currentSession = { ...session };
44
+ for (const augmenter of sessionAugmenters) {
45
+ const data = await augmenter(currentSession);
46
+ const existingFlags = currentSession.flags || {};
47
+ const newFlags = data?.flags || {};
48
+ currentSession = {
49
+ ...currentSession,
50
+ ...data,
51
+ flags: { ...existingFlags, ...newFlags },
52
+ };
53
+ }
54
+ return currentSession;
55
+ }
56
+ export async function augmentPasswordResetSession(session) {
57
+ let currentSession = { ...session };
58
+ for (const augmenter of passwordResetSessionAugmenters) {
59
+ const data = await augmenter(currentSession);
60
+ currentSession = { ...currentSession, ...data };
61
+ }
62
+ return currentSession;
63
+ }
@@ -0,0 +1,30 @@
1
+ import { type AuthRoutesConfig } from "./routes.js";
2
+ export interface AuthContext {
3
+ user: any;
4
+ session: any;
5
+ rbac: any;
6
+ passwordReset: any;
7
+ emailVerification: any;
8
+ auth: any;
9
+ routes?: AuthRoutesConfig;
10
+ }
11
+ /**
12
+ * Binds the resolved auth services. Called once by the composition root.
13
+ */
14
+ export declare function bindAuthContext(context: AuthContext): void;
15
+ /**
16
+ * Check whether auth context is currently bound.
17
+ */
18
+ export declare function isAuthContextBound(): boolean;
19
+ /**
20
+ * Returns the bound auth services.
21
+ *
22
+ * @throws If the auth service provider has not booted yet.
23
+ */
24
+ export declare function authContext(): AuthContext & {
25
+ routes: AuthRoutesConfig;
26
+ };
27
+ /**
28
+ * Resolves currently configured auth routes, falling back to defaults.
29
+ */
30
+ export declare function getAuthRoutes(): AuthRoutesConfig;
@@ -0,0 +1,36 @@
1
+ import { DEFAULT_AUTH_ROUTES } from "./routes.js";
2
+ const globalForAuthContext = globalThis;
3
+ /**
4
+ * Binds the resolved auth services. Called once by the composition root.
5
+ */
6
+ export function bindAuthContext(context) {
7
+ globalForAuthContext.__VEAP_AUTH_CONTEXT__ = {
8
+ ...context,
9
+ routes: context.routes || DEFAULT_AUTH_ROUTES,
10
+ };
11
+ }
12
+ /**
13
+ * Check whether auth context is currently bound.
14
+ */
15
+ export function isAuthContextBound() {
16
+ return globalForAuthContext.__VEAP_AUTH_CONTEXT__ !== undefined;
17
+ }
18
+ /**
19
+ * Returns the bound auth services.
20
+ *
21
+ * @throws If the auth service provider has not booted yet.
22
+ */
23
+ export function authContext() {
24
+ const context = globalForAuthContext.__VEAP_AUTH_CONTEXT__;
25
+ if (!context) {
26
+ throw new Error("[Auth] Context is not bound. AuthServiceProvider must boot before the auth facades are used.");
27
+ }
28
+ return context;
29
+ }
30
+ /**
31
+ * Resolves currently configured auth routes, falling back to defaults.
32
+ */
33
+ export function getAuthRoutes() {
34
+ const context = globalForAuthContext.__VEAP_AUTH_CONTEXT__;
35
+ return context?.routes || DEFAULT_AUTH_ROUTES;
36
+ }
@@ -0,0 +1,7 @@
1
+ export * from "./augment.js";
2
+ export * from "./context.js";
3
+ export * from "./logic.js";
4
+ export * from "./registry.js";
5
+ export * from "./routes.js";
6
+ export * from "./tokens.js";
7
+ export * from "./types.js";
@@ -0,0 +1,7 @@
1
+ export * from "./augment.js";
2
+ export * from "./context.js";
3
+ export * from "./logic.js";
4
+ export * from "./registry.js";
5
+ export * from "./routes.js";
6
+ export * from "./tokens.js";
7
+ export * from "./types.js";
@@ -0,0 +1,64 @@
1
+ import { augmentSession, augmentUser, registerIdentityAugmenter, registerPasswordResetSessionAugmenter, registerSessionAugmenter, unregisterIdentityAugmenter, unregisterPasswordResetSessionAugmenter, unregisterSessionAugmenter } from "./augment.js";
2
+ import { AuthCallbackRegistry } from "./registry.js";
3
+ import type { AuthResponse, FullUser, Session, User, UserPermission, UserRole } from "./types.js";
4
+ /**
5
+ * Registry for login validators (e.g. 2FA module)
6
+ */
7
+ export type AuthValidator = (userId: string) => Promise<AuthResponse | null>;
8
+ /**
9
+ * Registry for Security Requirements (e.g. checking if 2FA is needed for a session)
10
+ */
11
+ export type SecurityRequirement = (session: Session, user: FullUser,
12
+ /**
13
+ * Request path the security check is running for ("/app/jobs", "/", ...).
14
+ * Lets a requirement exempt the route that resolves its own gate (e.g. an
15
+ * onboarding wizard) and prevents redirect loops.
16
+ */
17
+ path?: string) => Promise<{
18
+ satisfied: boolean;
19
+ redirect?: string;
20
+ } | null>;
21
+ /**
22
+ * Registry for password reset validators (e.g. 2FA module requiring check during reset)
23
+ */
24
+ export type PasswordResetValidator = (userId: string) => Promise<AuthResponse | null>;
25
+ /**
26
+ * Registry for email verification validators
27
+ */
28
+ export type EmailVerificationValidator = (userId: string) => Promise<AuthResponse | null>;
29
+ export declare const authValidators: AuthCallbackRegistry<AuthValidator>;
30
+ export declare const securityRequirements: AuthCallbackRegistry<SecurityRequirement>;
31
+ export declare const passwordResetValidators: AuthCallbackRegistry<PasswordResetValidator>;
32
+ export declare const emailVerificationValidators: AuthCallbackRegistry<EmailVerificationValidator>;
33
+ export declare function registerAuthValidator(validator: AuthValidator): void;
34
+ export declare function registerAuthValidator(id: string, validator: AuthValidator): void;
35
+ export declare function unregisterAuthValidator(idOrValidator: string | AuthValidator): boolean;
36
+ export declare function registerPasswordResetValidator(validator: PasswordResetValidator): void;
37
+ export declare function registerPasswordResetValidator(id: string, validator: PasswordResetValidator): void;
38
+ export declare function unregisterPasswordResetValidator(idOrValidator: string | PasswordResetValidator): boolean;
39
+ export declare function registerEmailVerificationValidator(validator: EmailVerificationValidator): void;
40
+ export declare function registerEmailVerificationValidator(id: string, validator: EmailVerificationValidator): void;
41
+ export declare function unregisterEmailVerificationValidator(idOrValidator: string | EmailVerificationValidator): boolean;
42
+ export { augmentSession, augmentUser, registerIdentityAugmenter, registerPasswordResetSessionAugmenter, registerSessionAugmenter, unregisterIdentityAugmenter, unregisterPasswordResetSessionAugmenter, unregisterSessionAugmenter, };
43
+ export declare function registerSecurityRequirement(requirement: SecurityRequirement): void;
44
+ export declare function registerSecurityRequirement(id: string, requirement: SecurityRequirement): void;
45
+ export declare function unregisterSecurityRequirement(idOrRequirement: string | SecurityRequirement): boolean;
46
+ export declare function runPasswordResetValidators(userId: string): Promise<AuthResponse | null>;
47
+ export declare function runEmailVerificationValidators(userId: string): Promise<AuthResponse | null>;
48
+ /**
49
+ * Checks if the current session satisfies all registered security requirements.
50
+ */
51
+ export declare function checkSecurity(session: Session, user: FullUser, requiredRoles?: UserRole[], requiredPermissions?: UserPermission[], fallbackRedirect?: string,
52
+ /** Request path this check runs for; forwarded to modular requirements. */
53
+ path?: string): Promise<{
54
+ satisfied: boolean;
55
+ redirect: string | undefined;
56
+ } | {
57
+ satisfied: boolean;
58
+ redirect?: undefined;
59
+ }>;
60
+ /**
61
+ * Performs full augmentation on a user by merging core RBAC roles/permissions
62
+ * and running all registered modular identity augmenters.
63
+ */
64
+ export declare function performFullUserAugmentation(user: User, session?: Session): Promise<FullUser>;