@peterbud/nuxt-aegis 1.1.0-alpha

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 (134) hide show
  1. package/README.md +166 -0
  2. package/dist/module.d.mts +6 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +354 -0
  5. package/dist/runtime/app/composables/useAuth.d.ts +85 -0
  6. package/dist/runtime/app/composables/useAuth.js +187 -0
  7. package/dist/runtime/app/middleware/auth-logged-in.d.ts +16 -0
  8. package/dist/runtime/app/middleware/auth-logged-in.js +25 -0
  9. package/dist/runtime/app/middleware/auth-logged-out.d.ts +20 -0
  10. package/dist/runtime/app/middleware/auth-logged-out.js +17 -0
  11. package/dist/runtime/app/pages/AuthCallback.d.vue.ts +3 -0
  12. package/dist/runtime/app/pages/AuthCallback.vue +92 -0
  13. package/dist/runtime/app/pages/AuthCallback.vue.d.ts +3 -0
  14. package/dist/runtime/app/plugins/api.client.d.ts +11 -0
  15. package/dist/runtime/app/plugins/api.client.js +92 -0
  16. package/dist/runtime/app/plugins/api.server.d.ts +13 -0
  17. package/dist/runtime/app/plugins/api.server.js +28 -0
  18. package/dist/runtime/app/plugins/ssr-state.server.d.ts +2 -0
  19. package/dist/runtime/app/plugins/ssr-state.server.js +13 -0
  20. package/dist/runtime/app/router.options.d.ts +12 -0
  21. package/dist/runtime/app/router.options.js +11 -0
  22. package/dist/runtime/app/utils/logger.d.ts +18 -0
  23. package/dist/runtime/app/utils/logger.js +48 -0
  24. package/dist/runtime/app/utils/redirectValidation.d.ts +18 -0
  25. package/dist/runtime/app/utils/redirectValidation.js +21 -0
  26. package/dist/runtime/app/utils/routeMatching.d.ts +13 -0
  27. package/dist/runtime/app/utils/routeMatching.js +10 -0
  28. package/dist/runtime/app/utils/tokenStore.d.ts +24 -0
  29. package/dist/runtime/app/utils/tokenStore.js +14 -0
  30. package/dist/runtime/app/utils/tokenUtils.d.ts +17 -0
  31. package/dist/runtime/app/utils/tokenUtils.js +4 -0
  32. package/dist/runtime/server/middleware/auth.d.ts +6 -0
  33. package/dist/runtime/server/middleware/auth.js +82 -0
  34. package/dist/runtime/server/plugins/ssr-auth.d.ts +7 -0
  35. package/dist/runtime/server/plugins/ssr-auth.js +82 -0
  36. package/dist/runtime/server/providers/auth0.d.ts +12 -0
  37. package/dist/runtime/server/providers/auth0.js +57 -0
  38. package/dist/runtime/server/providers/github.d.ts +12 -0
  39. package/dist/runtime/server/providers/github.js +44 -0
  40. package/dist/runtime/server/providers/google.d.ts +12 -0
  41. package/dist/runtime/server/providers/google.js +46 -0
  42. package/dist/runtime/server/providers/mock.d.ts +37 -0
  43. package/dist/runtime/server/providers/mock.js +129 -0
  44. package/dist/runtime/server/providers/oauthBase.d.ts +72 -0
  45. package/dist/runtime/server/providers/oauthBase.js +183 -0
  46. package/dist/runtime/server/routes/impersonate.post.d.ts +21 -0
  47. package/dist/runtime/server/routes/impersonate.post.js +68 -0
  48. package/dist/runtime/server/routes/logout.post.d.ts +9 -0
  49. package/dist/runtime/server/routes/logout.post.js +24 -0
  50. package/dist/runtime/server/routes/me.get.d.ts +6 -0
  51. package/dist/runtime/server/routes/me.get.js +11 -0
  52. package/dist/runtime/server/routes/mock/authorize.get.d.ts +29 -0
  53. package/dist/runtime/server/routes/mock/authorize.get.js +103 -0
  54. package/dist/runtime/server/routes/mock/token.post.d.ts +31 -0
  55. package/dist/runtime/server/routes/mock/token.post.js +88 -0
  56. package/dist/runtime/server/routes/mock/userinfo.get.d.ts +27 -0
  57. package/dist/runtime/server/routes/mock/userinfo.get.js +59 -0
  58. package/dist/runtime/server/routes/password/change.post.d.ts +4 -0
  59. package/dist/runtime/server/routes/password/change.post.js +108 -0
  60. package/dist/runtime/server/routes/password/login-verify.get.d.ts +2 -0
  61. package/dist/runtime/server/routes/password/login-verify.get.js +79 -0
  62. package/dist/runtime/server/routes/password/login.post.d.ts +4 -0
  63. package/dist/runtime/server/routes/password/login.post.js +66 -0
  64. package/dist/runtime/server/routes/password/register-verify.get.d.ts +2 -0
  65. package/dist/runtime/server/routes/password/register-verify.get.js +86 -0
  66. package/dist/runtime/server/routes/password/register.post.d.ts +4 -0
  67. package/dist/runtime/server/routes/password/register.post.js +87 -0
  68. package/dist/runtime/server/routes/password/reset-complete.post.d.ts +4 -0
  69. package/dist/runtime/server/routes/password/reset-complete.post.js +75 -0
  70. package/dist/runtime/server/routes/password/reset-request.post.d.ts +5 -0
  71. package/dist/runtime/server/routes/password/reset-request.post.js +52 -0
  72. package/dist/runtime/server/routes/password/reset-verify.get.d.ts +2 -0
  73. package/dist/runtime/server/routes/password/reset-verify.get.js +50 -0
  74. package/dist/runtime/server/routes/refresh.post.d.ts +8 -0
  75. package/dist/runtime/server/routes/refresh.post.js +102 -0
  76. package/dist/runtime/server/routes/token.post.d.ts +28 -0
  77. package/dist/runtime/server/routes/token.post.js +90 -0
  78. package/dist/runtime/server/routes/unimpersonate.post.d.ts +16 -0
  79. package/dist/runtime/server/routes/unimpersonate.post.js +65 -0
  80. package/dist/runtime/server/tsconfig.json +3 -0
  81. package/dist/runtime/server/utils/auth.d.ts +94 -0
  82. package/dist/runtime/server/utils/auth.js +54 -0
  83. package/dist/runtime/server/utils/authCodeStore.d.ts +137 -0
  84. package/dist/runtime/server/utils/authCodeStore.js +123 -0
  85. package/dist/runtime/server/utils/cookies.d.ts +15 -0
  86. package/dist/runtime/server/utils/cookies.js +23 -0
  87. package/dist/runtime/server/utils/customClaims.d.ts +37 -0
  88. package/dist/runtime/server/utils/customClaims.js +45 -0
  89. package/dist/runtime/server/utils/handler.d.ts +77 -0
  90. package/dist/runtime/server/utils/handler.js +7 -0
  91. package/dist/runtime/server/utils/impersonation.d.ts +48 -0
  92. package/dist/runtime/server/utils/impersonation.js +259 -0
  93. package/dist/runtime/server/utils/jwt.d.ts +24 -0
  94. package/dist/runtime/server/utils/jwt.js +77 -0
  95. package/dist/runtime/server/utils/logger.d.ts +18 -0
  96. package/dist/runtime/server/utils/logger.js +49 -0
  97. package/dist/runtime/server/utils/magicCodeStore.d.ts +27 -0
  98. package/dist/runtime/server/utils/magicCodeStore.js +66 -0
  99. package/dist/runtime/server/utils/mockCodeStore.d.ts +89 -0
  100. package/dist/runtime/server/utils/mockCodeStore.js +71 -0
  101. package/dist/runtime/server/utils/password.d.ts +33 -0
  102. package/dist/runtime/server/utils/password.js +48 -0
  103. package/dist/runtime/server/utils/refreshToken.d.ts +74 -0
  104. package/dist/runtime/server/utils/refreshToken.js +108 -0
  105. package/dist/runtime/server/utils/resetSessionStore.d.ts +12 -0
  106. package/dist/runtime/server/utils/resetSessionStore.js +29 -0
  107. package/dist/runtime/tasks/cleanup/magic-codes.d.ts +10 -0
  108. package/dist/runtime/tasks/cleanup/magic-codes.js +79 -0
  109. package/dist/runtime/tasks/cleanup/refresh-tokens.d.ts +10 -0
  110. package/dist/runtime/tasks/cleanup/refresh-tokens.js +55 -0
  111. package/dist/runtime/tasks/cleanup/reset-sessions.d.ts +8 -0
  112. package/dist/runtime/tasks/cleanup/reset-sessions.js +45 -0
  113. package/dist/runtime/types/augmentation.d.ts +73 -0
  114. package/dist/runtime/types/augmentation.js +0 -0
  115. package/dist/runtime/types/authCode.d.ts +60 -0
  116. package/dist/runtime/types/authCode.js +0 -0
  117. package/dist/runtime/types/callbacks.d.ts +54 -0
  118. package/dist/runtime/types/callbacks.js +0 -0
  119. package/dist/runtime/types/config.d.ts +129 -0
  120. package/dist/runtime/types/config.js +0 -0
  121. package/dist/runtime/types/hooks.d.ts +118 -0
  122. package/dist/runtime/types/hooks.js +0 -0
  123. package/dist/runtime/types/index.d.ts +13 -0
  124. package/dist/runtime/types/index.js +1 -0
  125. package/dist/runtime/types/providers.d.ts +212 -0
  126. package/dist/runtime/types/providers.js +0 -0
  127. package/dist/runtime/types/refresh.d.ts +61 -0
  128. package/dist/runtime/types/refresh.js +0 -0
  129. package/dist/runtime/types/routes.d.ts +30 -0
  130. package/dist/runtime/types/routes.js +0 -0
  131. package/dist/runtime/types/token.d.ts +182 -0
  132. package/dist/runtime/types/token.js +0 -0
  133. package/dist/types.d.mts +7 -0
  134. package/package.json +80 -0
@@ -0,0 +1,29 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { useStorage } from "#imports";
3
+ import { createLogger } from "./logger.js";
4
+ const logger = createLogger("ResetSession");
5
+ export async function createResetSession(email, ttl = 300) {
6
+ const storage = useStorage();
7
+ const sessionId = randomBytes(32).toString("base64url");
8
+ const now = Date.now();
9
+ const data = {
10
+ email: email.toLowerCase(),
11
+ expiresAt: now + ttl * 1e3
12
+ };
13
+ await storage.setItem(`reset:${sessionId}`, data);
14
+ logger.debug(`Reset session created for ${email}`);
15
+ return sessionId;
16
+ }
17
+ export async function validateAndDeleteResetSession(sessionId) {
18
+ const storage = useStorage();
19
+ const key = `reset:${sessionId}`;
20
+ const data = await storage.getItem(key);
21
+ if (!data) {
22
+ return null;
23
+ }
24
+ await storage.removeItem(key);
25
+ if (Date.now() > data.expiresAt) {
26
+ return null;
27
+ }
28
+ return data.email;
29
+ }
@@ -0,0 +1,10 @@
1
+ declare const _default: import("nitropack").Task<{
2
+ totalProcessed: number;
3
+ deleted: number;
4
+ lookupKeysDeleted: number;
5
+ orphanedKeysDeleted: number;
6
+ skipped: number;
7
+ errors: number;
8
+ timestamp: string;
9
+ }>;
10
+ export default _default;
@@ -0,0 +1,79 @@
1
+ import { defineTask, useStorage } from "nitropack/runtime";
2
+ import { createLogger } from "../../server/utils/logger.js";
3
+ const logger = createLogger("Task:CleanupMagicCodes");
4
+ export default defineTask({
5
+ meta: {
6
+ name: "cleanup:magic-codes",
7
+ description: "Clean up expired magic codes and their lookup keys"
8
+ },
9
+ async run() {
10
+ logger.info("Starting magic code cleanup task...");
11
+ const storage = useStorage();
12
+ const now = Date.now();
13
+ const allKeys = await storage.getKeys();
14
+ const magicCodeKeys = allKeys.filter((key) => key.startsWith("magic:"));
15
+ const lookupKeys = allKeys.filter((key) => key.startsWith("magic-lookup:"));
16
+ let deletedCount = 0;
17
+ let errorCount = 0;
18
+ let skippedCount = 0;
19
+ const deletedLookupKeys = /* @__PURE__ */ new Set();
20
+ for (const key of magicCodeKeys) {
21
+ try {
22
+ const data = await storage.getItem(key);
23
+ if (!data) {
24
+ skippedCount++;
25
+ continue;
26
+ }
27
+ if (data.expiresAt < now) {
28
+ await storage.removeItem(key);
29
+ deletedCount++;
30
+ const lookupKey = `magic-lookup:${data.email}:${data.type}`;
31
+ deletedLookupKeys.add(lookupKey);
32
+ logger.debug(`Deleted expired magic code for ${data.email} (${data.type})`);
33
+ }
34
+ } catch (error) {
35
+ errorCount++;
36
+ logger.error(`Error processing magic code ${key}:`, error);
37
+ }
38
+ }
39
+ let lookupDeletedCount = 0;
40
+ for (const lookupKey of deletedLookupKeys) {
41
+ try {
42
+ await storage.removeItem(lookupKey);
43
+ lookupDeletedCount++;
44
+ } catch (error) {
45
+ errorCount++;
46
+ logger.error(`Error deleting lookup key ${lookupKey}:`, error);
47
+ }
48
+ }
49
+ let orphanedCount = 0;
50
+ for (const lookupKey of lookupKeys) {
51
+ try {
52
+ const code = await storage.getItem(lookupKey);
53
+ if (code) {
54
+ const magicCodeKey = `magic:${code}`;
55
+ const exists = await storage.getItem(magicCodeKey);
56
+ if (!exists) {
57
+ await storage.removeItem(lookupKey);
58
+ orphanedCount++;
59
+ logger.debug(`Deleted orphaned lookup key: ${lookupKey}`);
60
+ }
61
+ }
62
+ } catch (error) {
63
+ errorCount++;
64
+ logger.error(`Error processing lookup key ${lookupKey}:`, error);
65
+ }
66
+ }
67
+ const result = {
68
+ totalProcessed: magicCodeKeys.length,
69
+ deleted: deletedCount,
70
+ lookupKeysDeleted: lookupDeletedCount,
71
+ orphanedKeysDeleted: orphanedCount,
72
+ skipped: skippedCount,
73
+ errors: errorCount,
74
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
75
+ };
76
+ logger.info(`Magic code cleanup completed: ${deletedCount} codes deleted, ${lookupDeletedCount} lookup keys deleted, ${orphanedCount} orphaned keys deleted, ${skippedCount} skipped, ${errorCount} errors`);
77
+ return { result };
78
+ }
79
+ });
@@ -0,0 +1,10 @@
1
+ declare const _default: import("nitropack").Task<{
2
+ totalProcessed: number;
3
+ deleted: number;
4
+ expired: number;
5
+ revoked: number;
6
+ skipped: number;
7
+ errors: number;
8
+ timestamp: string;
9
+ }>;
10
+ export default _default;
@@ -0,0 +1,55 @@
1
+ import { defineTask, useStorage } from "nitropack/runtime";
2
+ import { getRefreshTokenData } from "../../server/utils/refreshToken.js";
3
+ import { createLogger } from "../../server/utils/logger.js";
4
+ const logger = createLogger("Task:CleanupRefreshTokens");
5
+ export default defineTask({
6
+ meta: {
7
+ name: "cleanup:refresh-tokens",
8
+ description: "Clean up expired and revoked refresh tokens from storage"
9
+ },
10
+ async run() {
11
+ logger.info("Starting refresh token cleanup task...");
12
+ const storage = useStorage("refreshTokenStore");
13
+ const keys = await storage.getKeys();
14
+ const now = Date.now();
15
+ let deletedCount = 0;
16
+ let revokedCount = 0;
17
+ let expiredCount = 0;
18
+ let errorCount = 0;
19
+ let skippedCount = 0;
20
+ for (const tokenHash of keys) {
21
+ try {
22
+ const data = await getRefreshTokenData(tokenHash);
23
+ if (!data) {
24
+ skippedCount++;
25
+ continue;
26
+ }
27
+ if (data.expiresAt < now || data.isRevoked) {
28
+ await storage.removeItem(tokenHash);
29
+ deletedCount++;
30
+ if (data.isRevoked) {
31
+ revokedCount++;
32
+ logger.debug(`Deleted revoked refresh token: ${tokenHash.substring(0, 8)}...`);
33
+ } else {
34
+ expiredCount++;
35
+ logger.debug(`Deleted expired refresh token: ${tokenHash.substring(0, 8)}...`);
36
+ }
37
+ }
38
+ } catch (error) {
39
+ errorCount++;
40
+ logger.error(`Error processing token ${tokenHash.substring(0, 8)}...:`, error);
41
+ }
42
+ }
43
+ const result = {
44
+ totalProcessed: keys.length,
45
+ deleted: deletedCount,
46
+ expired: expiredCount,
47
+ revoked: revokedCount,
48
+ skipped: skippedCount,
49
+ errors: errorCount,
50
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
51
+ };
52
+ logger.info(`Refresh token cleanup completed: ${deletedCount} deleted (${expiredCount} expired, ${revokedCount} revoked), ${skippedCount} skipped, ${errorCount} errors`);
53
+ return { result };
54
+ }
55
+ });
@@ -0,0 +1,8 @@
1
+ declare const _default: import("nitropack").Task<{
2
+ totalProcessed: number;
3
+ deleted: number;
4
+ skipped: number;
5
+ errors: number;
6
+ timestamp: string;
7
+ }>;
8
+ export default _default;
@@ -0,0 +1,45 @@
1
+ import { defineTask, useStorage } from "nitropack/runtime";
2
+ import { createLogger } from "../../server/utils/logger.js";
3
+ const logger = createLogger("Task:CleanupResetSessions");
4
+ export default defineTask({
5
+ meta: {
6
+ name: "cleanup:reset-sessions",
7
+ description: "Clean up expired password reset sessions"
8
+ },
9
+ async run() {
10
+ logger.info("Starting reset session cleanup task...");
11
+ const storage = useStorage();
12
+ const allKeys = await storage.getKeys();
13
+ const resetKeys = allKeys.filter((key) => key.startsWith("reset:"));
14
+ const now = Date.now();
15
+ let deletedCount = 0;
16
+ let errorCount = 0;
17
+ let skippedCount = 0;
18
+ for (const key of resetKeys) {
19
+ try {
20
+ const data = await storage.getItem(key);
21
+ if (!data) {
22
+ skippedCount++;
23
+ continue;
24
+ }
25
+ if (data.expiresAt < now) {
26
+ await storage.removeItem(key);
27
+ deletedCount++;
28
+ logger.debug(`Deleted expired reset session for ${data.email}`);
29
+ }
30
+ } catch (error) {
31
+ errorCount++;
32
+ logger.error(`Error processing reset session ${key}:`, error);
33
+ }
34
+ }
35
+ const result = {
36
+ totalProcessed: resetKeys.length,
37
+ deleted: deletedCount,
38
+ skipped: skippedCount,
39
+ errors: errorCount,
40
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
41
+ };
42
+ logger.info(`Reset session cleanup completed: ${deletedCount} deleted, ${skippedCount} skipped, ${errorCount} errors`);
43
+ return { result };
44
+ }
45
+ });
@@ -0,0 +1,73 @@
1
+ import type { NuxtAegisRuntimeConfig, RedirectConfig, LoggingConfig } from './config.js';
2
+ import type { TokenRefreshConfig } from './refresh.js';
3
+ import type { TokenPayload } from './token.js';
4
+ import type { ClientMiddlewareConfig } from './routes.js';
5
+ import type { SuccessHookPayload } from './hooks.js';
6
+ /**
7
+ * Module augmentations for external libraries
8
+ */
9
+ declare module '@nuxt/schema' {
10
+ interface RuntimeConfig {
11
+ nuxtAegis?: NuxtAegisRuntimeConfig;
12
+ }
13
+ interface PublicRuntimeConfig {
14
+ nuxtAegis: {
15
+ authPath: string;
16
+ loginPath: string;
17
+ callbackPath: string;
18
+ logoutPath: string;
19
+ refreshPath: string;
20
+ userInfoPath: string;
21
+ redirect: RedirectConfig;
22
+ tokenRefresh: TokenRefreshConfig;
23
+ clientMiddleware?: ClientMiddlewareConfig;
24
+ logging: LoggingConfig;
25
+ enableSSR: boolean;
26
+ };
27
+ }
28
+ }
29
+ declare module 'nitropack' {
30
+ interface NitroRuntimeHooks {
31
+ /**
32
+ * Hook called after successful authentication.
33
+ * Use this for logging, analytics, or database operations.
34
+ */
35
+ 'nuxt-aegis:success': (payload: SuccessHookPayload) => Promise<void> | void;
36
+ }
37
+ }
38
+ declare module 'h3' {
39
+ interface H3EventContext {
40
+ /**
41
+ * Authenticated user data from JWT token
42
+ * Available when request is authenticated via the auth middleware
43
+ */
44
+ user?: TokenPayload;
45
+ /**
46
+ * Original user data before impersonation
47
+ * Available when impersonation is active
48
+ */
49
+ originalUser?: {
50
+ sub: string;
51
+ email?: string;
52
+ name?: string;
53
+ };
54
+ }
55
+ }
56
+ declare module '#app' {
57
+ interface NuxtApp {
58
+ /**
59
+ * Custom $fetch instance with automatic bearer token injection
60
+ * Configured by the Nuxt Aegis plugin
61
+ */
62
+ $api: typeof $fetch;
63
+ }
64
+ }
65
+ declare module 'vue' {
66
+ interface ComponentCustomProperties {
67
+ /**
68
+ * Custom $fetch instance with automatic bearer token injection
69
+ * Configured by the Nuxt Aegis plugin
70
+ */
71
+ $api: typeof $fetch;
72
+ }
73
+ }
File without changes
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Authorization Code Flow Types
3
+ * Types for the CODE-based authentication flow
4
+ */
5
+ /**
6
+ * Authorization code data stored in the key-value store
7
+ */
8
+ export interface AuthCodeData {
9
+ /** Complete OAuth provider user data (NOT the JWT payload) - used for custom claims generation */
10
+ providerUserInfo: Record<string, unknown>;
11
+ /** Provider tokens received from OAuth provider */
12
+ providerTokens: {
13
+ /** OAuth provider access token */
14
+ access_token: string;
15
+ /** Optional OAuth provider refresh token */
16
+ refresh_token?: string;
17
+ /** Optional OAuth provider ID token (OpenID Connect) */
18
+ id_token?: string;
19
+ /** Optional token expiration time in seconds */
20
+ expires_in?: number;
21
+ };
22
+ /** Timestamp when the code expires (milliseconds since epoch) */
23
+ expiresAt: number;
24
+ /** Timestamp when the code was created (milliseconds since epoch) */
25
+ createdAt: number;
26
+ /** Provider name (e.g., 'google', 'github', 'microsoft', 'auth0') */
27
+ provider: string;
28
+ /** Resolved custom claims (already processed from static or callback config) */
29
+ customClaims?: Record<string, unknown>;
30
+ }
31
+ /**
32
+ * Request body for token exchange endpoint
33
+ * Client sends this to /auth/token to exchange CODE for tokens
34
+ */
35
+ export interface TokenExchangeRequest {
36
+ /** Authorization code received from OAuth callback */
37
+ code: string;
38
+ }
39
+ /**
40
+ * Response from token exchange endpoint
41
+ * Server returns access token in JSON response body
42
+ */
43
+ export interface TokenExchangeResponse {
44
+ /** JWT access token for API authentication */
45
+ accessToken: string;
46
+ /** Token type, always "Bearer" for JWT */
47
+ tokenType: 'Bearer';
48
+ /** Optional expiration time in seconds */
49
+ expiresIn?: number;
50
+ }
51
+ /**
52
+ * Configuration for authorization code flow
53
+ */
54
+ export interface AuthCodeConfig {
55
+ /**
56
+ * Expiration time for authorization codes in seconds
57
+ * @default 60
58
+ */
59
+ expiresIn: number;
60
+ }
File without changes
@@ -0,0 +1,54 @@
1
+ import type { H3Error, H3Event } from 'h3';
2
+ /**
3
+ * Callback and error handler type definitions
4
+ */
5
+ /**
6
+ * Error handler callback type
7
+ */
8
+ export type OnError = (event: H3Event, error: H3Error) => Promise<void> | void;
9
+ /**
10
+ * User information transformation hook
11
+ * Called after fetching user info from the provider, before storing it
12
+ * Allows provider-specific user object shaping
13
+ *
14
+ * This receives the complete OAuth provider response, NOT the JWT payload
15
+ *
16
+ * @param providerUserInfo - Complete user object from OAuth provider
17
+ * @param tokens - Provider tokens (access_token, refresh_token, id_token, expires_in)
18
+ * @param event - H3 event for server context access
19
+ * @returns Transformed user object that will be stored and used for custom claims
20
+ */
21
+ export type OnUserInfo = (providerUserInfo: Record<string, unknown>, tokens: {
22
+ access_token: string;
23
+ refresh_token?: string;
24
+ id_token?: string;
25
+ expires_in?: number;
26
+ }, event: H3Event) => Promise<Record<string, unknown>> | Record<string, unknown>;
27
+ /**
28
+ * Success hook parameters
29
+ */
30
+ export interface OnSuccessParams {
31
+ /** Transformed provider user data (post-onUserInfo transformation) */
32
+ providerUserInfo: Record<string, unknown>;
33
+ /** Provider tokens */
34
+ tokens: {
35
+ access_token: string;
36
+ refresh_token?: string;
37
+ id_token?: string;
38
+ expires_in?: number;
39
+ };
40
+ /** Provider name (e.g., 'google', 'github', 'microsoft', 'auth0') */
41
+ provider: string;
42
+ /** H3 event for server context access */
43
+ event: H3Event;
44
+ }
45
+ /**
46
+ * Success hook type
47
+ * Called after successful authentication, before generating authorization CODE
48
+ * Provider-agnostic hook for side effects like database storage
49
+ *
50
+ * This receives the transformed OAuth provider data, NOT the JWT payload
51
+ *
52
+ * @param params - Success hook parameters
53
+ */
54
+ export type OnSuccess = (params: OnSuccessParams) => Promise<void> | void;
File without changes
@@ -0,0 +1,129 @@
1
+ import type { GoogleProviderConfig, MicrosoftProviderConfig, GithubProviderConfig, Auth0ProviderConfig, MockProviderConfig, CustomProviderConfig, PasswordProviderConfig } from './providers.js';
2
+ import type { TokenConfig, ClaimsValidationConfig } from './token.js';
3
+ import type { TokenRefreshConfig } from './refresh.js';
4
+ import type { ClientMiddlewareConfig } from './routes.js';
5
+ import type { AuthCodeConfig } from './authCode.js';
6
+ /**
7
+ * Module and runtime configuration types
8
+ */
9
+ /**
10
+ * Redirect URL configuration
11
+ */
12
+ export interface RedirectConfig {
13
+ /** Redirect URL after logout (default: '/') */
14
+ logout?: string;
15
+ /** Redirect URL after successful authentication (default: '/') */
16
+ success?: string;
17
+ /** Redirect URL when authentication fails (default: '/') */
18
+ error?: string;
19
+ }
20
+ /**
21
+ * API endpoint path configuration
22
+ */
23
+ export interface EndpointConfig {
24
+ /** Base path for authentication API routes (default: '/auth') */
25
+ authPath?: string;
26
+ /** Base path for login endpoints without provider (default: '/auth'). Login URLs are constructed as '[loginPath]/[provider]' */
27
+ loginPath?: string;
28
+ /** Path for callback endpoints (default: '/auth/callback') */
29
+ callbackPath?: string;
30
+ /** Path for logout endpoint (default: '/auth/logout') */
31
+ logoutPath?: string;
32
+ /** Path for token refresh endpoint (default: '/auth/refresh') */
33
+ refreshPath?: string;
34
+ /** Path for user info endpoint (default: '/api/user/me') */
35
+ userInfoPath?: string;
36
+ }
37
+ /**
38
+ * Logging configuration
39
+ */
40
+ export interface LoggingConfig {
41
+ /** Log level: 'silent' | 'error' | 'warn' | 'info' | 'debug' (default: 'info') */
42
+ level?: 'silent' | 'error' | 'warn' | 'info' | 'debug';
43
+ /** Enable security event logging (default: false, enabled when level is 'debug') */
44
+ security?: boolean;
45
+ }
46
+ /**
47
+ * Impersonation configuration
48
+ */
49
+ export interface ImpersonationConfig {
50
+ /** Enable user impersonation feature (default: false, opt-in for security) */
51
+ enabled?: boolean;
52
+ /** Token expiration time for impersonated sessions in seconds (default: 900 = 15 minutes) */
53
+ tokenExpiration?: number;
54
+ }
55
+ /**
56
+ * Runtime config for Nuxt Aegis
57
+ */
58
+ export interface NuxtAegisRuntimeConfig {
59
+ token?: TokenConfig;
60
+ tokenRefresh?: TokenRefreshConfig;
61
+ authCode?: AuthCodeConfig;
62
+ endpoints?: EndpointConfig;
63
+ authPath?: string;
64
+ logging?: LoggingConfig;
65
+ impersonation?: ImpersonationConfig;
66
+ providers?: {
67
+ google?: GoogleProviderConfig;
68
+ microsoft?: MicrosoftProviderConfig;
69
+ github?: GithubProviderConfig;
70
+ auth0?: Auth0ProviderConfig;
71
+ mock?: MockProviderConfig;
72
+ password?: PasswordProviderConfig;
73
+ };
74
+ }
75
+ /**
76
+ * Nuxt Aegis module configuration options
77
+ */
78
+ export interface ModuleOptions {
79
+ /** Enable Nuxt DevTools integration (default: true) */
80
+ devtools?: boolean;
81
+ /**
82
+ * OAuth provider configurations
83
+ * Configure one or more authentication providers
84
+ */
85
+ providers?: {
86
+ /** Google OAuth provider configuration */
87
+ google?: GoogleProviderConfig;
88
+ /** Microsoft OAuth provider configuration */
89
+ microsoft?: MicrosoftProviderConfig;
90
+ /** GitHub OAuth provider configuration */
91
+ github?: GithubProviderConfig;
92
+ /** Auth0 OAuth provider configuration */
93
+ auth0?: Auth0ProviderConfig;
94
+ /** Mock OAuth provider configuration (development/testing only) */
95
+ mock?: MockProviderConfig;
96
+ /** Password provider configuration */
97
+ password?: PasswordProviderConfig;
98
+ /** Custom OAuth provider configurations */
99
+ custom?: CustomProviderConfig[];
100
+ };
101
+ /** Token configuration */
102
+ token?: TokenConfig;
103
+ /** Token refresh configuration */
104
+ tokenRefresh?: TokenRefreshConfig;
105
+ /**
106
+ * Authorization code configuration (CODE-based flow)
107
+ * Default: 60 seconds (recommended for security)
108
+ */
109
+ authCode?: AuthCodeConfig;
110
+ /** Redirect URL configuration */
111
+ redirect?: RedirectConfig;
112
+ /** Client-side middleware configuration for route protection */
113
+ clientMiddleware?: ClientMiddlewareConfig;
114
+ /** Claims validation configuration */
115
+ claimsValidation?: ClaimsValidationConfig;
116
+ /** API endpoint path configuration */
117
+ endpoints?: EndpointConfig;
118
+ /** Logging configuration */
119
+ logging?: LoggingConfig;
120
+ /** Impersonation configuration (opt-in feature) */
121
+ impersonation?: ImpersonationConfig;
122
+ /**
123
+ * Enable SSR-compatible authentication state restoration
124
+ * When true (default), authentication state will be restored on client after SSR hydration
125
+ * When false, plugin skips execution after server-side rendering (backward compatibility)
126
+ * @default true
127
+ */
128
+ enableSSR?: boolean;
129
+ }
File without changes
@@ -0,0 +1,118 @@
1
+ import type { H3Event } from 'h3';
2
+ import type { TokenPayload } from './token.js';
3
+ /**
4
+ * Nitro hook type definitions for Nuxt Aegis
5
+ * These hooks allow users to customize authentication behavior via server plugins
6
+ */
7
+ /**
8
+ * Payload for the nuxt-aegis:userInfo hook
9
+ * Called after fetching user info from the provider, before storing it
10
+ *
11
+ * This receives the complete OAuth provider response, NOT the JWT payload
12
+ */
13
+ export interface UserInfoHookPayload {
14
+ /** Complete user object from OAuth provider (e.g., Google, GitHub, Microsoft) */
15
+ providerUserInfo: Record<string, unknown>;
16
+ /** Provider tokens */
17
+ tokens: {
18
+ access_token: string;
19
+ refresh_token?: string;
20
+ id_token?: string;
21
+ expires_in?: number;
22
+ };
23
+ /** Provider name (e.g., 'google', 'github', 'microsoft', 'auth0') */
24
+ provider: string;
25
+ /** H3 event for server context access */
26
+ event: H3Event;
27
+ }
28
+ /**
29
+ * Payload for the nuxt-aegis:success hook
30
+ * Called after successful authentication
31
+ *
32
+ * This receives the transformed OAuth provider data, NOT the JWT payload
33
+ */
34
+ export interface SuccessHookPayload {
35
+ /** Transformed provider user data (post-userInfo hook transformation) */
36
+ providerUserInfo: Record<string, unknown>;
37
+ /** Provider tokens */
38
+ tokens: {
39
+ access_token: string;
40
+ refresh_token?: string;
41
+ id_token?: string;
42
+ expires_in?: number;
43
+ };
44
+ /** Provider name (e.g., 'google', 'github', 'microsoft', 'auth0') */
45
+ provider: string;
46
+ /** H3 event for server context access */
47
+ event: H3Event;
48
+ }
49
+ /**
50
+ * Payload for the nuxt-aegis:impersonate:check hook
51
+ * Called to determine if a user is allowed to impersonate others
52
+ */
53
+ export interface ImpersonateCheckPayload {
54
+ /** JWT payload of the user requesting impersonation */
55
+ requester: TokenPayload;
56
+ /** Target user ID to impersonate */
57
+ targetUserId: string;
58
+ /** Optional reason for impersonation (for audit) */
59
+ reason?: string;
60
+ /** H3 event for server context access */
61
+ event: H3Event;
62
+ /** Client IP address (for audit) */
63
+ ip: string;
64
+ /** User agent string (for audit) */
65
+ userAgent: string;
66
+ }
67
+ /**
68
+ * Payload for the nuxt-aegis:impersonate:fetchTarget hook
69
+ * Called to fetch the target user's data
70
+ *
71
+ * This hook MUST be implemented by the user to return the target user's data
72
+ */
73
+ export interface ImpersonateFetchTargetPayload {
74
+ /** JWT payload of the user requesting impersonation */
75
+ requester: TokenPayload;
76
+ /** Target user ID to impersonate */
77
+ targetUserId: string;
78
+ /** H3 event for server context access */
79
+ event: H3Event;
80
+ }
81
+ /**
82
+ * Payload for the nuxt-aegis:impersonate:start hook
83
+ * Called after impersonation starts successfully (fire-and-forget for audit logging)
84
+ */
85
+ export interface ImpersonateStartPayload {
86
+ /** JWT payload of the user who initiated impersonation */
87
+ requester: TokenPayload;
88
+ /** JWT payload of the impersonated user */
89
+ targetUser: TokenPayload;
90
+ /** Reason for impersonation */
91
+ reason?: string;
92
+ /** H3 event for server context access */
93
+ event: H3Event;
94
+ /** Client IP address (for audit) */
95
+ ip: string;
96
+ /** User agent string (for audit) */
97
+ userAgent: string;
98
+ /** Timestamp of impersonation */
99
+ timestamp: Date;
100
+ }
101
+ /**
102
+ * Payload for the nuxt-aegis:impersonate:end hook
103
+ * Called after impersonation ends successfully (fire-and-forget for audit logging)
104
+ */
105
+ export interface ImpersonateEndPayload {
106
+ /** JWT payload of the restored original user */
107
+ restoredUser: TokenPayload;
108
+ /** JWT payload of the user who was being impersonated */
109
+ impersonatedUser: TokenPayload;
110
+ /** H3 event for server context access */
111
+ event: H3Event;
112
+ /** Client IP address (for audit) */
113
+ ip: string;
114
+ /** User agent string (for audit) */
115
+ userAgent: string;
116
+ /** Timestamp when impersonation ended */
117
+ timestamp: Date;
118
+ }