@mars-stack/core 0.4.0

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 (192) hide show
  1. package/README.md +32 -0
  2. package/cursor/manifest.json +304 -0
  3. package/cursor/rules/mars-composition-patterns.mdc +186 -0
  4. package/cursor/rules/mars-data-access.mdc +26 -0
  5. package/cursor/rules/mars-project-structure.mdc +34 -0
  6. package/cursor/rules/mars-security.mdc +25 -0
  7. package/cursor/rules/mars-testing.mdc +24 -0
  8. package/cursor/rules/mars-ui-conventions.mdc +29 -0
  9. package/cursor/skills/mars-add-api-route/SKILL.md +120 -0
  10. package/cursor/skills/mars-add-audit-log/SKILL.md +373 -0
  11. package/cursor/skills/mars-add-blog/SKILL.md +447 -0
  12. package/cursor/skills/mars-add-command-palette/SKILL.md +438 -0
  13. package/cursor/skills/mars-add-component/SKILL.md +158 -0
  14. package/cursor/skills/mars-add-crud-routes/SKILL.md +221 -0
  15. package/cursor/skills/mars-add-e2e-test/SKILL.md +227 -0
  16. package/cursor/skills/mars-add-error-boundary/SKILL.md +472 -0
  17. package/cursor/skills/mars-add-feature/SKILL.md +174 -0
  18. package/cursor/skills/mars-add-middleware/SKILL.md +135 -0
  19. package/cursor/skills/mars-add-page/SKILL.md +153 -0
  20. package/cursor/skills/mars-add-prisma-model/SKILL.md +148 -0
  21. package/cursor/skills/mars-add-protected-resource/SKILL.md +192 -0
  22. package/cursor/skills/mars-add-role/SKILL.md +156 -0
  23. package/cursor/skills/mars-add-server-action/SKILL.md +167 -0
  24. package/cursor/skills/mars-add-webhook/SKILL.md +192 -0
  25. package/cursor/skills/mars-build-complete-feature/SKILL.md +228 -0
  26. package/cursor/skills/mars-build-dashboard/SKILL.md +211 -0
  27. package/cursor/skills/mars-build-data-table/SKILL.md +284 -0
  28. package/cursor/skills/mars-build-form/SKILL.md +229 -0
  29. package/cursor/skills/mars-build-landing-page/SKILL.md +248 -0
  30. package/cursor/skills/mars-capture-conversation-context/SKILL.md +119 -0
  31. package/cursor/skills/mars-configure-ai/SKILL.md +617 -0
  32. package/cursor/skills/mars-configure-analytics/SKILL.md +413 -0
  33. package/cursor/skills/mars-configure-dark-mode/SKILL.md +309 -0
  34. package/cursor/skills/mars-configure-email/SKILL.md +170 -0
  35. package/cursor/skills/mars-configure-email-verification/SKILL.md +333 -0
  36. package/cursor/skills/mars-configure-feature-flags/SKILL.md +361 -0
  37. package/cursor/skills/mars-configure-i18n/SKILL.md +518 -0
  38. package/cursor/skills/mars-configure-jobs/SKILL.md +500 -0
  39. package/cursor/skills/mars-configure-magic-links/SKILL.md +385 -0
  40. package/cursor/skills/mars-configure-multi-tenancy/SKILL.md +611 -0
  41. package/cursor/skills/mars-configure-notifications/SKILL.md +569 -0
  42. package/cursor/skills/mars-configure-oauth/SKILL.md +217 -0
  43. package/cursor/skills/mars-configure-onboarding/SKILL.md +483 -0
  44. package/cursor/skills/mars-configure-payments/SKILL.md +243 -0
  45. package/cursor/skills/mars-configure-realtime/SKILL.md +733 -0
  46. package/cursor/skills/mars-configure-search/SKILL.md +581 -0
  47. package/cursor/skills/mars-configure-storage/SKILL.md +273 -0
  48. package/cursor/skills/mars-configure-two-factor/SKILL.md +518 -0
  49. package/cursor/skills/mars-create-execution-plan/SKILL.md +204 -0
  50. package/cursor/skills/mars-create-seed/SKILL.md +191 -0
  51. package/cursor/skills/mars-deploy-to-vercel/SKILL.md +300 -0
  52. package/cursor/skills/mars-design-tokens/SKILL.md +138 -0
  53. package/cursor/skills/mars-setup-billing/SKILL.md +322 -0
  54. package/cursor/skills/mars-setup-project/SKILL.md +104 -0
  55. package/cursor/skills/mars-setup-teams/SKILL.md +688 -0
  56. package/cursor/skills/mars-test-api-route/SKILL.md +219 -0
  57. package/cursor/skills/mars-update-architecture-docs/SKILL.md +189 -0
  58. package/dist/api-error/index.d.ts +27 -0
  59. package/dist/api-error/index.d.ts.map +1 -0
  60. package/dist/api-error/index.js +2 -0
  61. package/dist/auth/credential-tag.d.ts +5 -0
  62. package/dist/auth/credential-tag.d.ts.map +1 -0
  63. package/dist/auth/credential-tag.js +2 -0
  64. package/dist/auth/crypto-utils.d.ts +43 -0
  65. package/dist/auth/crypto-utils.d.ts.map +1 -0
  66. package/dist/auth/crypto-utils.js +1 -0
  67. package/dist/auth/csrf.d.ts +32 -0
  68. package/dist/auth/csrf.d.ts.map +1 -0
  69. package/dist/auth/csrf.js +2 -0
  70. package/dist/auth/hooks/index.d.ts +4 -0
  71. package/dist/auth/hooks/index.d.ts.map +1 -0
  72. package/dist/auth/hooks/index.js +68 -0
  73. package/dist/auth/hooks/useCSRF.d.ts +7 -0
  74. package/dist/auth/hooks/useCSRF.d.ts.map +1 -0
  75. package/dist/auth/hooks/usePasswordStrength.d.ts +17 -0
  76. package/dist/auth/hooks/usePasswordStrength.d.ts.map +1 -0
  77. package/dist/auth/internal-api-key.d.ts +5 -0
  78. package/dist/auth/internal-api-key.d.ts.map +1 -0
  79. package/dist/auth/internal-api-key.js +30 -0
  80. package/dist/auth/link-utils.d.ts +13 -0
  81. package/dist/auth/link-utils.d.ts.map +1 -0
  82. package/dist/auth/link-utils.js +1 -0
  83. package/dist/auth/middleware.d.ts +56 -0
  84. package/dist/auth/middleware.d.ts.map +1 -0
  85. package/dist/auth/middleware.js +3 -0
  86. package/dist/auth/password.d.ts +28 -0
  87. package/dist/auth/password.d.ts.map +1 -0
  88. package/dist/auth/password.js +1 -0
  89. package/dist/auth/reset-token.d.ts +3 -0
  90. package/dist/auth/reset-token.d.ts.map +1 -0
  91. package/dist/auth/reset-token.js +9 -0
  92. package/dist/auth/responses.d.ts +15 -0
  93. package/dist/auth/responses.d.ts.map +1 -0
  94. package/dist/auth/responses.js +2 -0
  95. package/dist/auth/session.d.ts +79 -0
  96. package/dist/auth/session.d.ts.map +1 -0
  97. package/dist/auth/session.js +1 -0
  98. package/dist/auth/types.d.ts +18 -0
  99. package/dist/auth/types.d.ts.map +1 -0
  100. package/dist/auth/types.js +10 -0
  101. package/dist/auth/validation.d.ts +146 -0
  102. package/dist/auth/validation.d.ts.map +1 -0
  103. package/dist/auth/validation.js +116 -0
  104. package/dist/auth/validators.d.ts +4 -0
  105. package/dist/auth/validators.d.ts.map +1 -0
  106. package/dist/auth/validators.js +27 -0
  107. package/dist/auth/verification.d.ts +54 -0
  108. package/dist/auth/verification.d.ts.map +1 -0
  109. package/dist/auth/verification.js +39 -0
  110. package/dist/chunk-4LS3QDD5.js +162 -0
  111. package/dist/chunk-ABBUHT5Z.js +110 -0
  112. package/dist/chunk-CTYAVMOF.js +15 -0
  113. package/dist/chunk-GVLH2GQP.js +14 -0
  114. package/dist/chunk-HOSMMQMA.js +109 -0
  115. package/dist/chunk-MXQ66RUN.js +28 -0
  116. package/dist/chunk-PZE3JGXO.js +149 -0
  117. package/dist/chunk-QAH2Y5WK.js +93 -0
  118. package/dist/chunk-QWMN5UJC.js +76 -0
  119. package/dist/chunk-ROQV54MU.js +117 -0
  120. package/dist/chunk-U4NZQ366.js +46 -0
  121. package/dist/chunk-WBJOIENS.js +22 -0
  122. package/dist/chunk-WO6FHJHG.js +29 -0
  123. package/dist/chunk-Z5BEKPJI.js +96 -0
  124. package/dist/chunk-ZA46T6GX.js +24 -0
  125. package/dist/configure-mars.d.ts +104 -0
  126. package/dist/configure-mars.d.ts.map +1 -0
  127. package/dist/database/index.d.ts +8 -0
  128. package/dist/database/index.d.ts.map +1 -0
  129. package/dist/database/index.js +1 -0
  130. package/dist/email/index.d.ts +25 -0
  131. package/dist/email/index.d.ts.map +1 -0
  132. package/dist/email/index.js +2 -0
  133. package/dist/email/types.d.ts +18 -0
  134. package/dist/email/types.d.ts.map +1 -0
  135. package/dist/env/index.d.ts +36 -0
  136. package/dist/env/index.d.ts.map +1 -0
  137. package/dist/env/index.js +1 -0
  138. package/dist/index.d.ts +6 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +163 -0
  141. package/dist/logger/index.d.ts +80 -0
  142. package/dist/logger/index.d.ts.map +1 -0
  143. package/dist/logger/index.js +1 -0
  144. package/dist/payments/index.d.ts +53 -0
  145. package/dist/payments/index.d.ts.map +1 -0
  146. package/dist/payments/index.js +72 -0
  147. package/dist/plugin/builtin/email-plugins.d.ts +10 -0
  148. package/dist/plugin/builtin/email-plugins.d.ts.map +1 -0
  149. package/dist/plugin/builtin/index.d.ts +4 -0
  150. package/dist/plugin/builtin/index.d.ts.map +1 -0
  151. package/dist/plugin/builtin/index.js +324 -0
  152. package/dist/plugin/builtin/payment-plugins.d.ts +4 -0
  153. package/dist/plugin/builtin/payment-plugins.d.ts.map +1 -0
  154. package/dist/plugin/builtin/storage-plugins.d.ts +5 -0
  155. package/dist/plugin/builtin/storage-plugins.d.ts.map +1 -0
  156. package/dist/plugin/index.d.ts +21 -0
  157. package/dist/plugin/index.d.ts.map +1 -0
  158. package/dist/plugin/index.js +30 -0
  159. package/dist/rate-limit/index.d.ts +89 -0
  160. package/dist/rate-limit/index.d.ts.map +1 -0
  161. package/dist/rate-limit/index.js +166 -0
  162. package/dist/seo/faq.d.ts +37 -0
  163. package/dist/seo/faq.d.ts.map +1 -0
  164. package/dist/seo/index.d.ts +75 -0
  165. package/dist/seo/index.d.ts.map +1 -0
  166. package/dist/seo/index.js +1 -0
  167. package/dist/storage/index.d.ts +50 -0
  168. package/dist/storage/index.d.ts.map +1 -0
  169. package/dist/storage/index.js +211 -0
  170. package/dist/test-utils/factories.d.ts +38 -0
  171. package/dist/test-utils/factories.d.ts.map +1 -0
  172. package/dist/test-utils/index.d.ts +6 -0
  173. package/dist/test-utils/index.d.ts.map +1 -0
  174. package/dist/test-utils/index.js +117 -0
  175. package/dist/test-utils/mock-auth.d.ts +25 -0
  176. package/dist/test-utils/mock-auth.d.ts.map +1 -0
  177. package/dist/test-utils/mock-prisma.d.ts +55 -0
  178. package/dist/test-utils/mock-prisma.d.ts.map +1 -0
  179. package/dist/test-utils/render.d.ts +4 -0
  180. package/dist/test-utils/render.d.ts.map +1 -0
  181. package/dist/test-utils/request-helpers.d.ts +6 -0
  182. package/dist/test-utils/request-helpers.d.ts.map +1 -0
  183. package/dist/types.d.ts +53 -0
  184. package/dist/types.d.ts.map +1 -0
  185. package/dist/utils/math.d.ts +2 -0
  186. package/dist/utils/math.d.ts.map +1 -0
  187. package/dist/utils/math.js +7 -0
  188. package/dist/utils/optional-import.d.ts +14 -0
  189. package/dist/utils/optional-import.d.ts.map +1 -0
  190. package/package.json +205 -0
  191. package/scripts/generate-skill-adapters.ts +146 -0
  192. package/scripts/postinstall.mjs +146 -0
@@ -0,0 +1,30 @@
1
+ import { constantTimeEqual } from '../chunk-MXQ66RUN.js';
2
+ import 'server-only';
3
+
4
+ var MIN_INTERNAL_API_KEY_LENGTH = 32;
5
+ function parseInternalApiKeys() {
6
+ const raw = process.env.INTERNAL_API_KEY;
7
+ if (!raw) return [];
8
+ return raw.split(",").map((k) => k.trim()).filter((k) => k.length >= MIN_INTERNAL_API_KEY_LENGTH);
9
+ }
10
+ function getRequiredInternalApiKey() {
11
+ const keys = parseInternalApiKeys();
12
+ if (keys.length === 0) {
13
+ throw new Error("INTERNAL_API_KEY must be set and at least 32 characters long");
14
+ }
15
+ return keys[0];
16
+ }
17
+ function getInternalApiKeys() {
18
+ return parseInternalApiKeys();
19
+ }
20
+ function isInternalApiRequestAuthorized(authHeader, expectedApiKeys) {
21
+ if (!authHeader) return false;
22
+ const keys = Array.isArray(expectedApiKeys) ? expectedApiKeys : [expectedApiKeys];
23
+ for (const key of keys) {
24
+ const expected = `Bearer ${key}`;
25
+ if (constantTimeEqual(authHeader, expected)) return true;
26
+ }
27
+ return false;
28
+ }
29
+
30
+ export { getInternalApiKeys, getRequiredInternalApiKey, isInternalApiRequestAuthorized };
@@ -0,0 +1,13 @@
1
+ export interface BuildEmailVerificationUrlParams {
2
+ baseUrl: string;
3
+ token: string;
4
+ }
5
+ export interface BuildPasswordResetUrlParams {
6
+ baseUrl: string;
7
+ token: string;
8
+ email: string;
9
+ }
10
+ export declare function normalizeEmailFromQueryParam(rawEmail: string): string;
11
+ export declare function buildEmailVerificationUrl({ baseUrl, token, }: BuildEmailVerificationUrlParams): string;
12
+ export declare function buildPasswordResetUrl({ baseUrl, token, email, }: BuildPasswordResetUrlParams): string;
13
+ //# sourceMappingURL=link-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-utils.d.ts","sourceRoot":"","sources":["../../src/auth/link-utils.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErE;AAED,wBAAgB,yBAAyB,CAAC,EACxC,OAAO,EACP,KAAK,GACN,EAAE,+BAA+B,GAAG,MAAM,CAE1C;AAED,wBAAgB,qBAAqB,CAAC,EACpC,OAAO,EACP,KAAK,EACL,KAAK,GACN,EAAE,2BAA2B,GAAG,MAAM,CAKtC"}
@@ -0,0 +1 @@
1
+ export { buildEmailVerificationUrl, buildPasswordResetUrl, normalizeEmailFromQueryParam } from '../chunk-WBJOIENS.js';
@@ -0,0 +1,56 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import type { SessionPayload } from './session';
3
+ export interface AuthenticatedRequest extends NextRequest {
4
+ session: SessionPayload;
5
+ }
6
+ export type AuthenticatedAPIHandler = (request: AuthenticatedRequest, context: {
7
+ params: Promise<{
8
+ [key: string]: string;
9
+ }>;
10
+ }) => Promise<NextResponse>;
11
+ export type AuthenticatedAPIHandlerNoParams = (request: AuthenticatedRequest) => Promise<NextResponse>;
12
+ export type AuthenticatedAPIHandlerSimple = () => Promise<NextResponse>;
13
+ interface AuthMiddlewareConfig {
14
+ verifySession: () => Promise<SessionPayload | null>;
15
+ findUserRole: (userId: string) => Promise<string | null>;
16
+ }
17
+ /**
18
+ * Creates authentication middleware wrappers for Next.js API routes.
19
+ * All wrappers verify the session, attach it to the request, and return
20
+ * appropriate HTTP error responses on failure.
21
+ *
22
+ * @param config - Configuration with session verifier and role lookup
23
+ * @returns An object containing withAuth, withAuthNoParams, withAuthSimple, withRole, and withOwnership wrappers
24
+ * @example
25
+ * const { withAuth, withRole, withOwnership } = createAuthMiddleware({
26
+ * verifySession: () => sessions.verifySessionForAPI(),
27
+ * findUserRole: (userId) => db.user.findRole(userId),
28
+ * });
29
+ * export const GET = withAuth(async (req, ctx) => { ... });
30
+ * export const DELETE = withRole(['admin'], async (req, ctx) => { ... });
31
+ */
32
+ export declare function createAuthMiddleware(config: AuthMiddlewareConfig): {
33
+ withAuth: (handler: AuthenticatedAPIHandler) => (request: NextRequest, context: {
34
+ params: Promise<{
35
+ [key: string]: string;
36
+ }>;
37
+ }) => Promise<NextResponse>;
38
+ withAuthNoParams: (handler: AuthenticatedAPIHandlerNoParams) => (request: NextRequest) => Promise<NextResponse>;
39
+ withAuthSimple: (handler: AuthenticatedAPIHandlerSimple) => (_request: NextRequest) => Promise<NextResponse>;
40
+ withRole: (allowedRoles: string[], handler: AuthenticatedAPIHandler) => (request: NextRequest, context: {
41
+ params: Promise<{
42
+ [key: string]: string;
43
+ }>;
44
+ }) => Promise<NextResponse>;
45
+ withOwnership: (getResourceUserId: (request: AuthenticatedRequest, context: {
46
+ params: Promise<{
47
+ [key: string]: string;
48
+ }>;
49
+ }) => Promise<string | null | undefined>, handler: AuthenticatedAPIHandler) => (request: NextRequest, context: {
50
+ params: Promise<{
51
+ [key: string]: string;
52
+ }>;
53
+ }) => Promise<NextResponse>;
54
+ };
55
+ export {};
56
+ //# sourceMappingURL=middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/auth/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAGhD,MAAM,WAAW,oBAAqB,SAAQ,WAAW;IACvD,OAAO,EAAE,cAAc,CAAC;CACzB;AAED,MAAM,MAAM,uBAAuB,GAAG,CACpC,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,KACpD,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3B,MAAM,MAAM,+BAA+B,GAAG,CAC5C,OAAO,EAAE,oBAAoB,KAC1B,OAAO,CAAC,YAAY,CAAC,CAAC;AAE3B,MAAM,MAAM,6BAA6B,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;AAExE,UAAU,oBAAoB;IAC5B,aAAa,EAAE,MAAM,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACpD,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC1D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB;wBACpC,uBAAuB,MAE9C,SAAS,WAAW,EACpB,SAAS;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,KACtD,OAAO,CAAC,YAAY,CAAC;gCAgBS,+BAA+B,MAClD,SAAS,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC;8BAgB3B,6BAA6B,MAC9C,UAAU,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC;6BAa7B,MAAM,EAAE,WAAW,uBAAuB,eAjD7D,WAAW,WACX;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,KACtD,OAAO,CAAC,YAAY,CAAC;uCA6DL,CACjB,OAAO,EAAE,oBAAoB,EAC7B,OAAO,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,KACpD,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,WAC9B,uBAAuB,eAnErB,WAAW,WACX;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,KACtD,OAAO,CAAC,YAAY,CAAC;EAyF3B"}
@@ -0,0 +1,3 @@
1
+ export { createAuthMiddleware } from '../chunk-QWMN5UJC.js';
2
+ import '../chunk-ZA46T6GX.js';
3
+ import '../chunk-MXQ66RUN.js';
@@ -0,0 +1,28 @@
1
+ import 'server-only';
2
+ import { z } from 'zod';
3
+ /** Zod schema enforcing password strength rules: 8-100 chars, mixed case, digit, special char, no common patterns. */
4
+ export declare const passwordSchema: z.ZodString;
5
+ /**
6
+ * Hashes a password using SHA-256 prehash followed by bcrypt (cost 12).
7
+ * The prehash step allows bcrypt to work with passwords of any length while
8
+ * maintaining a domain separator to prevent cross-protocol collisions.
9
+ *
10
+ * @param password - The plaintext password to hash
11
+ * @returns The bcrypt hash string
12
+ * @example
13
+ * const hash = await hashPassword('mySecureP@ss1');
14
+ */
15
+ export declare function hashPassword(password: string): Promise<string>;
16
+ /**
17
+ * Verifies a plaintext password against a stored bcrypt hash.
18
+ * Attempts prehashed comparison first, then falls back to direct comparison
19
+ * for backwards compatibility with legacy hashes.
20
+ *
21
+ * @param plainPassword - The plaintext password to verify
22
+ * @param hashedPassword - The stored bcrypt hash
23
+ * @returns True if the password matches
24
+ * @example
25
+ * const valid = await verifyPassword('mySecureP@ss1', storedHash);
26
+ */
27
+ export declare function verifyPassword(plainPassword: string, hashedPassword: string): Promise<boolean>;
28
+ //# sourceMappingURL=password.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/auth/password.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,sHAAsH;AACtH,eAAO,MAAM,cAAc,aAYqE,CAAC;AAEjG;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAIpE;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,cAAc,CAClC,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC,CAMlB"}
@@ -0,0 +1 @@
1
+ export { hashPassword, passwordSchema, verifyPassword } from '../chunk-WO6FHJHG.js';
@@ -0,0 +1,3 @@
1
+ import 'server-only';
2
+ export declare function hashPasswordResetToken(token: string): Promise<string>;
3
+ //# sourceMappingURL=reset-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset-token.d.ts","sourceRoot":"","sources":["../../src/auth/reset-token.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAMrB,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE3E"}
@@ -0,0 +1,9 @@
1
+ import { hashToken } from '../chunk-MXQ66RUN.js';
2
+ import 'server-only';
3
+
4
+ var RESET_TOKEN_DOMAIN = "reset-token-v1";
5
+ async function hashPasswordResetToken(token) {
6
+ return hashToken(token, RESET_TOKEN_DOMAIN);
7
+ }
8
+
9
+ export { hashPasswordResetToken };
@@ -0,0 +1,15 @@
1
+ import 'server-only';
2
+ import { NextResponse } from 'next/server';
3
+ export declare const AUTH_RESPONSES: {
4
+ readonly UNAUTHORIZED: () => NextResponse<{
5
+ error: string;
6
+ }>;
7
+ readonly FORBIDDEN: () => NextResponse<{
8
+ error: string;
9
+ }>;
10
+ readonly SERVER_ERROR: () => NextResponse<{
11
+ error: string;
12
+ }>;
13
+ };
14
+ export declare function validateOwnership(resourceUserId: string, sessionUserId: string): boolean;
15
+ //# sourceMappingURL=responses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/auth/responses.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAErB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,eAAO,MAAM,cAAc;;;;;;;;;;CAajB,CAAC;AAEX,wBAAgB,iBAAiB,CAAC,cAAc,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAExF"}
@@ -0,0 +1,2 @@
1
+ export { AUTH_RESPONSES, validateOwnership } from '../chunk-ZA46T6GX.js';
2
+ import '../chunk-MXQ66RUN.js';
@@ -0,0 +1,79 @@
1
+ import 'server-only';
2
+ export interface SessionPayload {
3
+ userId: string;
4
+ email: string;
5
+ name: string;
6
+ role: string;
7
+ fingerprint: string;
8
+ emailVerified: boolean;
9
+ credentialTag: string;
10
+ createdAt: number;
11
+ expiresAt: number;
12
+ lastActivity: number;
13
+ }
14
+ /**
15
+ * Encrypts a session payload into a JWE token using AES-256-GCM with a HKDF-derived key.
16
+ *
17
+ * @param payload - The session data to encrypt
18
+ * @param secret - The JWT secret used to derive the encryption key
19
+ * @returns The encrypted JWE token string
20
+ * @example
21
+ * const token = await encrypt(sessionPayload, process.env.JWT_SECRET);
22
+ */
23
+ export declare function encrypt(payload: SessionPayload, secret: string): Promise<string>;
24
+ /**
25
+ * Decrypts a JWE session token and validates expiration, inactivity, and absolute lifetime.
26
+ * Deletes the session cookie if decryption fails (e.g. legacy/corrupted cookie).
27
+ *
28
+ * @param session - The encrypted JWE token string (or undefined)
29
+ * @param secret - The JWT secret used to derive the decryption key
30
+ * @returns The decrypted session payload, or null if invalid/expired
31
+ * @example
32
+ * const session = await decrypt(cookieValue, process.env.JWT_SECRET);
33
+ * if (session) console.log(session.userId);
34
+ */
35
+ export declare function decrypt(session: string | undefined, secret: string): Promise<SessionPayload | null>;
36
+ interface SessionManagerConfig {
37
+ getJWTSecret: () => string;
38
+ signInRoute: string;
39
+ validateCredential: (userId: string, credentialTag: string) => Promise<boolean>;
40
+ }
41
+ /**
42
+ * Creates a session manager with methods for creating, reading, updating, and
43
+ * deleting encrypted HTTP-only session cookies. Uses HKDF-derived keys and
44
+ * validates credential tags against the database on every read.
45
+ *
46
+ * @param config - Configuration with JWT secret accessor, sign-in route, and credential validator
47
+ * @returns An object with session lifecycle methods
48
+ * @example
49
+ * const sessions = createSessionManager({
50
+ * getJWTSecret: () => env.JWT_SECRET,
51
+ * signInRoute: '/sign-in',
52
+ * validateCredential: async (userId, tag) => db.user.checkCredential(userId, tag),
53
+ * });
54
+ * await sessions.createSession(user);
55
+ */
56
+ export declare function createSessionManager(config: SessionManagerConfig): {
57
+ createSession: (user: {
58
+ id: string;
59
+ email: string;
60
+ name: string;
61
+ role: string;
62
+ emailVerified: boolean;
63
+ credentialTag: string;
64
+ }) => Promise<void>;
65
+ getSession: () => Promise<SessionPayload | null>;
66
+ updateSession: () => Promise<void>;
67
+ deleteSession: () => Promise<void>;
68
+ verifySession: () => Promise<SessionPayload>;
69
+ verifySessionForAPI: () => Promise<SessionPayload | null>;
70
+ getCurrentUser: () => Promise<{
71
+ id: string;
72
+ email: string;
73
+ name: string;
74
+ role: string;
75
+ emailVerified: boolean;
76
+ } | null>;
77
+ };
78
+ export {};
79
+ //# sourceMappingURL=session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/auth/session.ts"],"names":[],"mappings":"AAAA,OAAO,aAAa,CAAC;AAwCrB,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;GAQG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAMtF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,SAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAkC9G;AAED,UAAU,oBAAoB;IAC5B,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACjF;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB;0BAC5B;QACjC,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,OAAO,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC;KACvB,KAAG,OAAO,CAAC,IAAI,CAAC;sBA6BY,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;yBAiB3B,OAAO,CAAC,IAAI,CAAC;yBAyBb,OAAO,CAAC,IAAI,CAAC;yBAKP,OAAO,CAAC,cAAc,CAAC;+BAUjB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;0BAKzC,OAAO,CAAC;QACvC,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,aAAa,EAAE,OAAO,CAAC;KACxB,GAAG,IAAI,CAAC;EAsBV"}
@@ -0,0 +1 @@
1
+ export { createSessionManager, decrypt, encrypt } from '../chunk-4LS3QDD5.js';
@@ -0,0 +1,18 @@
1
+ export interface AuthError {
2
+ code: string;
3
+ message: string;
4
+ }
5
+ export interface AuthUser {
6
+ id: string;
7
+ email: string;
8
+ name?: string;
9
+ role: string;
10
+ emailVerified: boolean;
11
+ }
12
+ export declare enum AuthErrorCode {
13
+ INVALID_CREDENTIALS = "invalid_credentials",
14
+ EMAIL_NOT_VERIFIED = "email_not_verified",
15
+ ACCOUNT_LOCKED = "account_locked",
16
+ SERVER_ERROR = "server_error"
17
+ }
18
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,oBAAY,aAAa;IACvB,mBAAmB,wBAAwB;IAC3C,kBAAkB,uBAAuB;IACzC,cAAc,mBAAmB;IACjC,YAAY,iBAAiB;CAC9B"}
@@ -0,0 +1,10 @@
1
+ // src/auth/types.ts
2
+ var AuthErrorCode = /* @__PURE__ */ ((AuthErrorCode2) => {
3
+ AuthErrorCode2["INVALID_CREDENTIALS"] = "invalid_credentials";
4
+ AuthErrorCode2["EMAIL_NOT_VERIFIED"] = "email_not_verified";
5
+ AuthErrorCode2["ACCOUNT_LOCKED"] = "account_locked";
6
+ AuthErrorCode2["SERVER_ERROR"] = "server_error";
7
+ return AuthErrorCode2;
8
+ })(AuthErrorCode || {});
9
+
10
+ export { AuthErrorCode };
@@ -0,0 +1,146 @@
1
+ import { z } from 'zod';
2
+ /** Individual field-level Zod schemas for email, password, name, token, and confirmPassword. */
3
+ export declare const fieldSchemas: {
4
+ email: z.ZodString;
5
+ password: z.ZodString;
6
+ name: z.ZodString;
7
+ token: z.ZodString;
8
+ confirmPassword: z.ZodString;
9
+ };
10
+ /** Client-side form validation schemas with cross-field refinements (e.g. password confirmation). */
11
+ export declare const formSchemas: {
12
+ login: z.ZodObject<{
13
+ email: z.ZodString;
14
+ password: z.ZodString;
15
+ }, z.core.$strip>;
16
+ signup: z.ZodObject<{
17
+ email: z.ZodString;
18
+ password: z.ZodString;
19
+ name: z.ZodOptional<z.ZodString>;
20
+ confirmPassword: z.ZodString;
21
+ termsAccepted: z.ZodBoolean;
22
+ marketingOptIn: z.ZodOptional<z.ZodBoolean>;
23
+ }, z.core.$strip>;
24
+ forgotPassword: z.ZodObject<{
25
+ email: z.ZodString;
26
+ }, z.core.$strip>;
27
+ resetPassword: z.ZodObject<{
28
+ token: z.ZodString;
29
+ email: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodString>;
30
+ password: z.ZodString;
31
+ confirmPassword: z.ZodString;
32
+ }, z.core.$strip>;
33
+ emailVerification: z.ZodObject<{
34
+ token: z.ZodString;
35
+ email: z.ZodOptional<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodString>>;
36
+ }, z.core.$strip>;
37
+ };
38
+ /** Server-side API validation schemas (no confirmPassword field — that's a client concern). */
39
+ export declare const apiSchemas: {
40
+ login: z.ZodObject<{
41
+ email: z.ZodString;
42
+ password: z.ZodString;
43
+ }, z.core.$strip>;
44
+ signup: z.ZodObject<{
45
+ email: z.ZodString;
46
+ password: z.ZodString;
47
+ name: z.ZodOptional<z.ZodString>;
48
+ termsAccepted: z.ZodBoolean;
49
+ marketingOptIn: z.ZodOptional<z.ZodBoolean>;
50
+ }, z.core.$strip>;
51
+ forgotPassword: z.ZodObject<{
52
+ email: z.ZodString;
53
+ }, z.core.$strip>;
54
+ resetPassword: z.ZodObject<{
55
+ token: z.ZodString;
56
+ email: z.ZodString;
57
+ password: z.ZodString;
58
+ }, z.core.$strip>;
59
+ emailVerification: z.ZodObject<{
60
+ token: z.ZodString;
61
+ email: z.ZodOptional<z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodString>>;
62
+ }, z.core.$strip>;
63
+ };
64
+ export type LoginFormData = z.infer<typeof formSchemas.login>;
65
+ export type SignupFormData = z.infer<typeof formSchemas.signup>;
66
+ export type ForgotPasswordFormData = z.infer<typeof formSchemas.forgotPassword>;
67
+ export type ResetPasswordFormData = z.infer<typeof formSchemas.resetPassword>;
68
+ export type EmailVerificationData = z.infer<typeof formSchemas.emailVerification>;
69
+ /**
70
+ * Calculates a password strength score based on character diversity and common pattern avoidance.
71
+ *
72
+ * @param password - The password to evaluate
73
+ * @returns An object with a numeric score (0-7) and a strength label
74
+ * @example
75
+ * const { score, strength } = getPasswordStrength('MyP@ss99!');
76
+ * // { score: 7, strength: 'Strong' }
77
+ */
78
+ export declare function getPasswordStrength(password: string): {
79
+ score: number;
80
+ strength: 'Weak' | 'Medium' | 'Strong';
81
+ };
82
+ /**
83
+ * Returns a boolean map of which password requirements are satisfied.
84
+ * Useful for rendering a live requirements checklist in signup forms.
85
+ *
86
+ * @param password - The password to check
87
+ * @returns An object with boolean flags for each requirement
88
+ * @example
89
+ * const reqs = getPasswordRequirements('Hello1!');
90
+ * // { length: false, lowercase: true, uppercase: true, number: true, special: true, ... }
91
+ */
92
+ export declare function getPasswordRequirements(password: string): {
93
+ length: boolean;
94
+ lowercase: boolean;
95
+ uppercase: boolean;
96
+ number: boolean;
97
+ special: boolean;
98
+ noPassword: boolean;
99
+ noSequential: boolean;
100
+ };
101
+ /**
102
+ * Validates a single value against a Zod schema.
103
+ *
104
+ * @param schema - The Zod schema to validate against
105
+ * @param value - The value to validate
106
+ * @returns The first error message string, or null if valid
107
+ * @example
108
+ * const error = validateField(fieldSchemas.email, 'bad');
109
+ * // 'Please enter a valid email address'
110
+ */
111
+ export declare function validateField<T extends z.ZodSchema>(schema: T, value: unknown): string | null;
112
+ /**
113
+ * Validates a complete form data object against a Zod schema.
114
+ *
115
+ * @param schema - The Zod schema to validate against
116
+ * @param data - The form data object to validate
117
+ * @returns An object with success flag, parsed data (or null), and a path-keyed errors map
118
+ * @example
119
+ * const result = validateForm(formSchemas.login, { email: '', password: '' });
120
+ * // { success: false, data: null, errors: { email: 'Email is required', ... } }
121
+ */
122
+ export declare function validateForm<T extends z.ZodSchema>(schema: T, data: unknown): {
123
+ success: boolean;
124
+ data: z.core.output<T>;
125
+ errors: {};
126
+ } | {
127
+ success: boolean;
128
+ data: null;
129
+ errors: Record<string, string>;
130
+ };
131
+ export declare const passwordSchema: z.ZodString;
132
+ export declare const loginSchema: z.ZodObject<{
133
+ email: z.ZodString;
134
+ password: z.ZodString;
135
+ }, z.core.$strip>;
136
+ export declare const signupSchema: z.ZodObject<{
137
+ email: z.ZodString;
138
+ password: z.ZodString;
139
+ name: z.ZodOptional<z.ZodString>;
140
+ termsAccepted: z.ZodBoolean;
141
+ marketingOptIn: z.ZodOptional<z.ZodBoolean>;
142
+ }, z.core.$strip>;
143
+ export declare const forgotPasswordSchema: z.ZodObject<{
144
+ email: z.ZodString;
145
+ }, z.core.$strip>;
146
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/auth/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,gGAAgG;AAChG,eAAO,MAAM,YAAY;;;;;;CAwBxB,CAAC;AA0CF,qGAAqG;AACrG,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBvB,CAAC;AAEF,+FAA+F;AAC/F,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;CAoBtB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;AAC9D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;AAChE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,cAAc,CAAC,CAAC;AAChF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,aAAa,CAAC,CAAC;AAC9E,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,iBAAiB,CAAC,CAAC;AAElF;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,GACf;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;CAAE,CAa3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM;;;;;;;;EAUvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,iBAG7E;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO;;;;;;;;EAW3E;AAED,eAAO,MAAM,cAAc,aAAwB,CAAC;AACpD,eAAO,MAAM,WAAW;;;iBAAmB,CAAC;AAC5C,eAAO,MAAM,YAAY;;;;;;iBAAoB,CAAC;AAC9C,eAAO,MAAM,oBAAoB;;iBAA4B,CAAC"}
@@ -0,0 +1,116 @@
1
+ import { normalizeEmailFromQueryParam } from '../chunk-WBJOIENS.js';
2
+ import { z } from 'zod';
3
+
4
+ var fieldSchemas = {
5
+ email: z.string().min(1, "Email is required").email("Please enter a valid email address"),
6
+ password: z.string().min(8, "Password must be at least 8 characters").max(100, "Password must be less than 100 characters").regex(/[A-Z]/, "Password must contain at least one uppercase letter").regex(/[a-z]/, "Password must contain at least one lowercase letter").regex(/[0-9]/, "Password must contain at least one number").regex(/[^A-Za-z0-9]/, "Password must contain at least one special character").refine((password) => !password.toLowerCase().includes("password"), "Password cannot contain 'password'").refine((password) => !password.includes("123"), "Password cannot contain sequential numbers"),
7
+ name: z.string().min(1, "Name is required").min(2, "Name must be at least 2 characters").max(100, "Name must be less than 100 characters").regex(/^[a-zA-Z\s'-]+$/, "Name can only contain letters, spaces, hyphens, and apostrophes"),
8
+ token: z.string().min(1, "Token is required"),
9
+ confirmPassword: z.string().min(1, "Please confirm your password")
10
+ };
11
+ var baseSchemas = {
12
+ login: z.object({
13
+ email: fieldSchemas.email,
14
+ password: z.string().min(1, "Password is required")
15
+ }),
16
+ signupBase: z.object({
17
+ email: fieldSchemas.email,
18
+ password: fieldSchemas.password,
19
+ name: fieldSchemas.name.optional(),
20
+ confirmPassword: fieldSchemas.confirmPassword,
21
+ termsAccepted: z.boolean().refine((val) => val === true, "You must accept the terms and conditions"),
22
+ marketingOptIn: z.boolean().optional()
23
+ }),
24
+ forgotPassword: z.object({
25
+ email: fieldSchemas.email
26
+ }),
27
+ resetPasswordBase: z.object({
28
+ token: fieldSchemas.token,
29
+ email: z.preprocess(
30
+ (value) => typeof value === "string" ? normalizeEmailFromQueryParam(value) : value,
31
+ fieldSchemas.email
32
+ ),
33
+ password: fieldSchemas.password,
34
+ confirmPassword: fieldSchemas.confirmPassword
35
+ }),
36
+ emailVerification: z.object({
37
+ token: fieldSchemas.token,
38
+ email: z.preprocess(
39
+ (value) => typeof value === "string" ? normalizeEmailFromQueryParam(value) : value,
40
+ fieldSchemas.email
41
+ ).optional()
42
+ })
43
+ };
44
+ var formSchemas = {
45
+ login: baseSchemas.login,
46
+ signup: baseSchemas.signupBase.refine((data) => data.password === data.confirmPassword, {
47
+ message: "Passwords do not match",
48
+ path: ["confirmPassword"]
49
+ }),
50
+ forgotPassword: baseSchemas.forgotPassword,
51
+ resetPassword: baseSchemas.resetPasswordBase.refine(
52
+ (data) => data.password === data.confirmPassword,
53
+ { message: "Passwords do not match", path: ["confirmPassword"] }
54
+ ),
55
+ emailVerification: baseSchemas.emailVerification
56
+ };
57
+ var apiSchemas = {
58
+ login: baseSchemas.login,
59
+ signup: z.object({
60
+ email: fieldSchemas.email,
61
+ password: fieldSchemas.password,
62
+ name: fieldSchemas.name.optional(),
63
+ termsAccepted: z.boolean().refine((val) => val === true, "You must accept the terms and conditions"),
64
+ marketingOptIn: z.boolean().optional()
65
+ }),
66
+ forgotPassword: baseSchemas.forgotPassword,
67
+ resetPassword: z.object({
68
+ token: fieldSchemas.token,
69
+ email: fieldSchemas.email,
70
+ password: fieldSchemas.password
71
+ }),
72
+ emailVerification: baseSchemas.emailVerification
73
+ };
74
+ function getPasswordStrength(password) {
75
+ let score = 0;
76
+ if (password.length >= 8) score++;
77
+ if (/[a-z]/.test(password)) score++;
78
+ if (/[A-Z]/.test(password)) score++;
79
+ if (/[0-9]/.test(password)) score++;
80
+ if (/[^A-Za-z0-9]/.test(password)) score++;
81
+ if (!password.toLowerCase().includes("password")) score++;
82
+ if (!password.includes("123")) score++;
83
+ const strength = score >= 6 ? "Strong" : score >= 4 ? "Medium" : "Weak";
84
+ return { score, strength };
85
+ }
86
+ function getPasswordRequirements(password) {
87
+ return {
88
+ length: password.length >= 8 && password.length <= 100,
89
+ lowercase: /[a-z]/.test(password),
90
+ uppercase: /[A-Z]/.test(password),
91
+ number: /[0-9]/.test(password),
92
+ special: /[^A-Za-z0-9]/.test(password),
93
+ noPassword: !password.toLowerCase().includes("password"),
94
+ noSequential: !password.includes("123")
95
+ };
96
+ }
97
+ function validateField(schema, value) {
98
+ const result = schema.safeParse(value);
99
+ return result.success ? null : result.error.issues[0]?.message || "Invalid value";
100
+ }
101
+ function validateForm(schema, data) {
102
+ const result = schema.safeParse(data);
103
+ if (result.success) return { success: true, data: result.data, errors: {} };
104
+ const errors = {};
105
+ result.error.issues.forEach((issue) => {
106
+ const path = issue.path.join(".");
107
+ errors[path] = issue.message;
108
+ });
109
+ return { success: false, data: null, errors };
110
+ }
111
+ var passwordSchema = fieldSchemas.password;
112
+ var loginSchema = apiSchemas.login;
113
+ var signupSchema = apiSchemas.signup;
114
+ var forgotPasswordSchema = apiSchemas.forgotPassword;
115
+
116
+ export { apiSchemas, fieldSchemas, forgotPasswordSchema, formSchemas, getPasswordRequirements, getPasswordStrength, loginSchema, passwordSchema, signupSchema, validateField, validateForm };
@@ -0,0 +1,4 @@
1
+ export declare function validateEmail(value: string): string | undefined;
2
+ export declare function validatePassword(value: string): string | undefined;
3
+ export declare function validateRequired(fieldName: string): (value: string) => string | undefined;
4
+ //# sourceMappingURL=validators.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.ts","sourceRoot":"","sources":["../../src/auth/validators.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO/D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUlE;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,IACxC,OAAO,MAAM,KAAG,MAAM,GAAG,SAAS,CAI3C"}
@@ -0,0 +1,27 @@
1
+ import { passwordSchema } from '../chunk-WO6FHJHG.js';
2
+
3
+ // src/auth/validators.ts
4
+ function validateEmail(value) {
5
+ if (!value) return "Email is required";
6
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
7
+ if (!emailRegex.test(value)) return "Please enter a valid email address";
8
+ return void 0;
9
+ }
10
+ function validatePassword(value) {
11
+ if (!value) return "Password is required";
12
+ try {
13
+ passwordSchema.parse(value);
14
+ return void 0;
15
+ } catch (error) {
16
+ if (error instanceof Error) return error.message;
17
+ return "Password validation failed";
18
+ }
19
+ }
20
+ function validateRequired(fieldName) {
21
+ return (value) => {
22
+ if (!value) return `${fieldName} is required`;
23
+ return void 0;
24
+ };
25
+ }
26
+
27
+ export { validateEmail, validatePassword, validateRequired };