@cloudauth/core 0.1.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 (134) hide show
  1. package/LICENSE +21 -0
  2. package/dist/adapter.d.ts +20 -0
  3. package/dist/adapter.d.ts.map +1 -0
  4. package/dist/adapter.js +2 -0
  5. package/dist/adapter.js.map +1 -0
  6. package/dist/additional-fields.d.ts +31 -0
  7. package/dist/additional-fields.d.ts.map +1 -0
  8. package/dist/additional-fields.js +2 -0
  9. package/dist/additional-fields.js.map +1 -0
  10. package/dist/auth.d.ts +26 -0
  11. package/dist/auth.d.ts.map +1 -0
  12. package/dist/auth.js +280 -0
  13. package/dist/auth.js.map +1 -0
  14. package/dist/config.d.ts +55 -0
  15. package/dist/config.d.ts.map +1 -0
  16. package/dist/config.js +2 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/cookies.d.ts +29 -0
  19. package/dist/cookies.d.ts.map +1 -0
  20. package/dist/cookies.js +98 -0
  21. package/dist/cookies.js.map +1 -0
  22. package/dist/crypto.d.ts +23 -0
  23. package/dist/crypto.d.ts.map +1 -0
  24. package/dist/crypto.js +57 -0
  25. package/dist/crypto.js.map +1 -0
  26. package/dist/csrf.d.ts +6 -0
  27. package/dist/csrf.d.ts.map +1 -0
  28. package/dist/csrf.js +24 -0
  29. package/dist/csrf.js.map +1 -0
  30. package/dist/encryption.d.ts +10 -0
  31. package/dist/encryption.d.ts.map +1 -0
  32. package/dist/encryption.js +61 -0
  33. package/dist/encryption.js.map +1 -0
  34. package/dist/errors.d.ts +29 -0
  35. package/dist/errors.d.ts.map +1 -0
  36. package/dist/errors.js +57 -0
  37. package/dist/errors.js.map +1 -0
  38. package/dist/hooks.d.ts +45 -0
  39. package/dist/hooks.d.ts.map +1 -0
  40. package/dist/hooks.js +2 -0
  41. package/dist/hooks.js.map +1 -0
  42. package/dist/http.d.ts +23 -0
  43. package/dist/http.d.ts.map +1 -0
  44. package/dist/http.js +126 -0
  45. package/dist/http.js.map +1 -0
  46. package/dist/index.d.ts +23 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +53 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/provider.d.ts +19 -0
  51. package/dist/provider.d.ts.map +1 -0
  52. package/dist/provider.js +2 -0
  53. package/dist/provider.js.map +1 -0
  54. package/dist/rate-limiter.d.ts +33 -0
  55. package/dist/rate-limiter.d.ts.map +1 -0
  56. package/dist/rate-limiter.js +45 -0
  57. package/dist/rate-limiter.js.map +1 -0
  58. package/dist/test/adapter-conformance.d.ts +13 -0
  59. package/dist/test/adapter-conformance.d.ts.map +1 -0
  60. package/dist/test/adapter-conformance.js +212 -0
  61. package/dist/test/adapter-conformance.js.map +1 -0
  62. package/dist/test/cookies.test.d.ts +2 -0
  63. package/dist/test/cookies.test.d.ts.map +1 -0
  64. package/dist/test/cookies.test.js +83 -0
  65. package/dist/test/cookies.test.js.map +1 -0
  66. package/dist/test/crypto.test.d.ts +2 -0
  67. package/dist/test/crypto.test.d.ts.map +1 -0
  68. package/dist/test/crypto.test.js +84 -0
  69. package/dist/test/crypto.test.js.map +1 -0
  70. package/dist/test/encryption.test.d.ts +2 -0
  71. package/dist/test/encryption.test.d.ts.map +1 -0
  72. package/dist/test/encryption.test.js +34 -0
  73. package/dist/test/encryption.test.js.map +1 -0
  74. package/dist/test/factories.d.ts +11 -0
  75. package/dist/test/factories.d.ts.map +1 -0
  76. package/dist/test/factories.js +110 -0
  77. package/dist/test/factories.js.map +1 -0
  78. package/dist/test/index.d.ts +6 -0
  79. package/dist/test/index.d.ts.map +1 -0
  80. package/dist/test/index.js +4 -0
  81. package/dist/test/index.js.map +1 -0
  82. package/dist/test/mock-provider.d.ts +34 -0
  83. package/dist/test/mock-provider.d.ts.map +1 -0
  84. package/dist/test/mock-provider.js +99 -0
  85. package/dist/test/mock-provider.js.map +1 -0
  86. package/dist/test/rate-limiter.test.d.ts +2 -0
  87. package/dist/test/rate-limiter.test.d.ts.map +1 -0
  88. package/dist/test/rate-limiter.test.js +38 -0
  89. package/dist/test/rate-limiter.test.js.map +1 -0
  90. package/dist/test/url.test.d 2.ts +2 -0
  91. package/dist/test/url.test.d.ts +2 -0
  92. package/dist/test/url.test.d.ts 2.map +1 -0
  93. package/dist/test/url.test.d.ts.map +1 -0
  94. package/dist/test/url.test.js +40 -0
  95. package/dist/test/url.test.js 2.map +1 -0
  96. package/dist/test/url.test.js.map +1 -0
  97. package/dist/types.d.ts +109 -0
  98. package/dist/types.d.ts.map +1 -0
  99. package/dist/types.js +2 -0
  100. package/dist/types.js.map +1 -0
  101. package/dist/url.d.ts +11 -0
  102. package/dist/url.d.ts.map +1 -0
  103. package/dist/url.js +35 -0
  104. package/dist/url.js.map +1 -0
  105. package/package.json +27 -0
  106. package/src/adapter.ts +39 -0
  107. package/src/additional-fields.ts +53 -0
  108. package/src/auth.ts +355 -0
  109. package/src/config.ts +62 -0
  110. package/src/cookies.ts +123 -0
  111. package/src/crypto.ts +62 -0
  112. package/src/csrf.ts +27 -0
  113. package/src/encryption.ts +88 -0
  114. package/src/errors.ts +65 -0
  115. package/src/hooks.ts +54 -0
  116. package/src/http.ts +192 -0
  117. package/src/index.ts +161 -0
  118. package/src/provider.ts +21 -0
  119. package/src/rate-limiter.ts +64 -0
  120. package/src/test/adapter-conformance.ts +267 -0
  121. package/src/test/cookies.test.ts +99 -0
  122. package/src/test/crypto.test.ts +103 -0
  123. package/src/test/encryption.test.ts +40 -0
  124. package/src/test/factories.ts +139 -0
  125. package/src/test/index.ts +17 -0
  126. package/src/test/mock-provider.ts +130 -0
  127. package/src/test/rate-limiter.test.ts +49 -0
  128. package/src/test/url.test.ts +48 -0
  129. package/src/types.ts +122 -0
  130. package/src/url.ts +35 -0
  131. package/tsconfig 2.tsbuildinfo +1 -0
  132. package/tsconfig.json +11 -0
  133. package/tsconfig.tsbuildinfo +1 -0
  134. package/vitest.config.ts +14 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CloudAuth
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.
@@ -0,0 +1,20 @@
1
+ import type { User, Account, Session, SessionWithUser, OAuthState, CreateUserInput, UpdateUserInput, CreateAccountInput, CreateSessionInput, UpdateSessionInput, CreateOAuthStateInput } from './types.js';
2
+ export interface AuthAdapter {
3
+ createUser(data: CreateUserInput): Promise<User>;
4
+ getUserById(id: string): Promise<User | null>;
5
+ getUserByEmail(email: string): Promise<User | null>;
6
+ updateUser(id: string, data: UpdateUserInput): Promise<User>;
7
+ createAccount(data: CreateAccountInput): Promise<Account>;
8
+ getAccount(provider: string, providerAccountId: string): Promise<Account | null>;
9
+ getAccountsByUserId(userId: string): Promise<Account[]>;
10
+ linkAccount(userId: string, data: CreateAccountInput): Promise<Account>;
11
+ deleteAccount(accountId: string): Promise<void>;
12
+ createSession(data: CreateSessionInput): Promise<Session>;
13
+ getSessionByTokenHash(tokenHash: string): Promise<SessionWithUser | null>;
14
+ updateSession(id: string, data: UpdateSessionInput): Promise<Session>;
15
+ deleteSession(tokenHash: string): Promise<void>;
16
+ deleteExpiredSessions(): Promise<void>;
17
+ createOAuthState(data: CreateOAuthStateInput): Promise<void>;
18
+ consumeOAuthState(stateHash: string): Promise<OAuthState | null>;
19
+ }
20
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,OAAO,EACP,OAAO,EACP,eAAe,EACf,UAAU,EACV,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACtB,MAAM,YAAY,CAAA;AAEnB,MAAM,WAAW,WAAW;IAE1B,UAAU,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAChD,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IAC7C,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAA;IACnD,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAG5D,aAAa,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACzD,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAA;IAChF,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;IACvD,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACvE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAG/C,aAAa,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACzD,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAA;IACzE,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACrE,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/C,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAGtC,gBAAgB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5D,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;CACjE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ import type { User } from './types.js';
2
+ export interface StringField {
3
+ type: 'string';
4
+ defaultValue?: string;
5
+ input?: boolean;
6
+ }
7
+ export interface BooleanField {
8
+ type: 'boolean';
9
+ defaultValue?: boolean;
10
+ input?: boolean;
11
+ }
12
+ export interface NumberField {
13
+ type: 'number';
14
+ defaultValue?: number;
15
+ input?: boolean;
16
+ }
17
+ export interface DateField {
18
+ type: 'date';
19
+ defaultValue?: Date;
20
+ input?: boolean;
21
+ }
22
+ export type AdditionalField = StringField | BooleanField | NumberField | DateField;
23
+ export type AdditionalFieldsConfig = Record<string, AdditionalField>;
24
+ export type InferFieldType<T extends AdditionalField> = T extends StringField ? string : T extends BooleanField ? boolean : T extends NumberField ? number : T extends DateField ? Date : unknown;
25
+ export type InferAdditionalFields<T extends AdditionalFieldsConfig> = {
26
+ [K in keyof T]: InferFieldType<T[K]>;
27
+ } & {};
28
+ export interface InferTypes<TAdditional extends AdditionalFieldsConfig = Record<string, never>> {
29
+ User: User & InferAdditionalFields<TAdditional>;
30
+ }
31
+ //# sourceMappingURL=additional-fields.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"additional-fields.d.ts","sourceRoot":"","sources":["../src/additional-fields.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAItC,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAA;IACf,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,QAAQ,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,IAAI,CAAA;IACnB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED,MAAM,MAAM,eAAe,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,GAAG,SAAS,CAAA;AAElF,MAAM,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;AAIpE,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,eAAe,IAAI,CAAC,SAAS,WAAW,GACzE,MAAM,GACN,CAAC,SAAS,YAAY,GACpB,OAAO,GACP,CAAC,SAAS,WAAW,GACnB,MAAM,GACN,CAAC,SAAS,SAAS,GACjB,IAAI,GACJ,OAAO,CAAA;AAEjB,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,sBAAsB,IAAI;KACnE,CAAC,IAAI,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CACrC,GAAG,EAAE,CAAA;AAIN,MAAM,WAAW,UAAU,CAAC,WAAW,SAAS,sBAAsB,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC;IAC5F,IAAI,EAAE,IAAI,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAA;CAChD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=additional-fields.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"additional-fields.js","sourceRoot":"","sources":["../src/additional-fields.ts"],"names":[],"mappings":""}
package/dist/auth.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ import type { AuthConfig } from './config.js';
2
+ import type { SessionWithUser, User, Session } from './types.js';
3
+ import type { HooksConfig } from './hooks.js';
4
+ export interface AuthResponse {
5
+ session: Session;
6
+ user: User;
7
+ cookieHeader: string;
8
+ }
9
+ /**
10
+ * Generate the authorization URL to redirect the user to the provider.
11
+ */
12
+ export declare function createAuthUrl(config: AuthConfig, providerId: string, _request?: Request): Promise<URL>;
13
+ /**
14
+ * Handle the OAuth callback from the provider.
15
+ */
16
+ export declare function handleCallback(config: AuthConfig, providerId: string, request: Request, hooks?: HooksConfig): Promise<AuthResponse>;
17
+ /**
18
+ * Get the current session from a request.
19
+ * Validates the session cookie, checks expiry, and returns session with user.
20
+ */
21
+ export declare function getSession(config: AuthConfig, request: Request): Promise<SessionWithUser | null>;
22
+ /**
23
+ * Sign out a user by deleting their session and returning a cleared cookie.
24
+ */
25
+ export declare function signOut(config: AuthConfig, request: Request, hooks?: HooksConfig): Promise<string>;
26
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AAQhE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAG7C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,IAAI,CAAA;IACV,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,OAAO,GACjB,OAAO,CAAC,GAAG,CAAC,CA6Bd;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,YAAY,CAAC,CA8JvB;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAyCjC;AAED;;GAEG;AACH,wBAAsB,OAAO,CAC3B,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,MAAM,CAAC,CAyCjB"}
package/dist/auth.js ADDED
@@ -0,0 +1,280 @@
1
+ import { generateSessionToken, hashToken, generateCodeVerifier, generateCodeChallenge, } from './crypto.js';
2
+ import { signCookie, verifyCookie, serializeCookie } from './cookies.js';
3
+ import { InvalidStateError } from './errors.js';
4
+ /**
5
+ * Generate the authorization URL to redirect the user to the provider.
6
+ */
7
+ export async function createAuthUrl(config, providerId, _request) {
8
+ const provider = findProvider(config.providers, providerId);
9
+ const adapter = config.database;
10
+ const codeVerifier = generateCodeVerifier();
11
+ const state = generateSessionToken();
12
+ const stateHash = await hashToken(state);
13
+ const codeChallenge = await generateCodeChallenge(codeVerifier);
14
+ const callbackUrl = buildCallbackUrl(config, providerId);
15
+ const redirectUri = buildRedirectUri(config, providerId);
16
+ // Persist OAuth state for callback validation
17
+ await adapter.createOAuthState({
18
+ stateHash,
19
+ codeVerifier,
20
+ provider: providerId,
21
+ callbackUrl,
22
+ errorUrl: undefined,
23
+ expiresAt: new Date(Date.now() + 600_000), // 10 minute expiry
24
+ });
25
+ const authUrl = provider.authorizationUrl({
26
+ state,
27
+ codeVerifier: codeChallenge,
28
+ redirectUri,
29
+ });
30
+ return authUrl;
31
+ }
32
+ /**
33
+ * Handle the OAuth callback from the provider.
34
+ */
35
+ export async function handleCallback(config, providerId, request, hooks) {
36
+ const provider = findProvider(config.providers, providerId);
37
+ const adapter = config.database;
38
+ const secret = config.security?.secret;
39
+ const sessionConfig = config.session ?? {};
40
+ const url = new URL(request.url);
41
+ const code = url.searchParams.get('code');
42
+ const state = url.searchParams.get('state');
43
+ const error = url.searchParams.get('error');
44
+ // Handle provider error (user denied consent, etc.)
45
+ if (error) {
46
+ throw new Error(`Provider returned error: ${error}`);
47
+ }
48
+ if (!code || !state) {
49
+ throw new InvalidStateError('Missing code or state parameter');
50
+ }
51
+ // Validate and consume OAuth state (single-use)
52
+ const stateHash = await hashToken(state);
53
+ const storedState = await adapter.consumeOAuthState(stateHash);
54
+ if (!storedState) {
55
+ throw new InvalidStateError();
56
+ }
57
+ // Exchange code for tokens
58
+ const redirectUri = buildRedirectUri(config, providerId);
59
+ const tokenSet = await provider.exchangeCode({
60
+ code,
61
+ codeVerifier: storedState.codeVerifier,
62
+ redirectUri,
63
+ });
64
+ // Fetch provider profile
65
+ const profile = await provider.getProfile(tokenSet);
66
+ // Run beforeSignIn hook (if configured)
67
+ if (hooks?.beforeSignIn) {
68
+ await hooks.beforeSignIn({ adapter, profile, request });
69
+ }
70
+ // Find or create user
71
+ const existingAccount = await adapter.getAccount(providerId, profile.providerAccountId);
72
+ let user;
73
+ if (existingAccount) {
74
+ // Existing account — get the user
75
+ const existingUser = await adapter.getUserById(existingAccount.userId);
76
+ if (!existingUser) {
77
+ throw new Error('User not found for existing account');
78
+ }
79
+ user = existingUser;
80
+ }
81
+ else {
82
+ // New account — find or create user by email
83
+ const existingUser = profile.email ? await adapter.getUserByEmail(profile.email) : null;
84
+ if (existingUser) {
85
+ user = existingUser;
86
+ // Link the new provider account
87
+ const linkedAccount = await adapter.linkAccount(user.id, {
88
+ userId: user.id,
89
+ provider: providerId,
90
+ providerAccountId: profile.providerAccountId,
91
+ accessToken: config.security?.storeProviderTokens ? tokenSet.accessToken : null,
92
+ refreshToken: config.security?.storeProviderTokens ? (tokenSet.refreshToken ?? null) : null,
93
+ idToken: config.security?.storeProviderTokens ? (tokenSet.idToken ?? null) : null,
94
+ scope: tokenSet.scope ?? null,
95
+ tokenType: tokenSet.tokenType ?? null,
96
+ expiresAt: tokenSet.expiresAt ? new Date(Date.now() + tokenSet.expiresAt * 1000) : null,
97
+ });
98
+ if (hooks?.onAccountLinked) {
99
+ await hooks.onAccountLinked({ adapter, user, account: linkedAccount });
100
+ }
101
+ }
102
+ else {
103
+ // Create new user
104
+ user = await adapter.createUser({
105
+ email: profile.email ?? null,
106
+ emailVerified: profile.emailVerified ?? false,
107
+ name: profile.name ?? null,
108
+ image: profile.image ?? null,
109
+ });
110
+ // Create account
111
+ await adapter.createAccount({
112
+ userId: user.id,
113
+ provider: providerId,
114
+ providerAccountId: profile.providerAccountId,
115
+ accessToken: config.security?.storeProviderTokens ? tokenSet.accessToken : null,
116
+ refreshToken: config.security?.storeProviderTokens ? (tokenSet.refreshToken ?? null) : null,
117
+ idToken: config.security?.storeProviderTokens ? (tokenSet.idToken ?? null) : null,
118
+ scope: tokenSet.scope ?? null,
119
+ tokenType: tokenSet.tokenType ?? null,
120
+ expiresAt: tokenSet.expiresAt ? new Date(Date.now() + tokenSet.expiresAt * 1000) : null,
121
+ });
122
+ if (hooks?.onUserCreated) {
123
+ await hooks.onUserCreated({ adapter, user });
124
+ }
125
+ }
126
+ }
127
+ // Run afterSignIn hook
128
+ if (hooks?.afterSignIn) {
129
+ const fakeSession = {
130
+ id: '',
131
+ userId: user.id,
132
+ tokenHash: '',
133
+ expiresAt: new Date(),
134
+ ipAddress: null,
135
+ userAgent: null,
136
+ createdAt: new Date(),
137
+ updatedAt: new Date(),
138
+ };
139
+ await hooks.afterSignIn({ adapter, session: fakeSession, user, profile });
140
+ }
141
+ // Create session
142
+ const sessionToken = generateSessionToken();
143
+ const tokenHash = await hashToken(sessionToken);
144
+ const expiresInMs = (sessionConfig.expiresIn ?? 30 * 24 * 60 * 60) * 1000;
145
+ if (hooks?.beforeSessionCreated) {
146
+ await hooks.beforeSessionCreated({ adapter, user });
147
+ }
148
+ const session = await adapter.createSession({
149
+ userId: user.id,
150
+ tokenHash,
151
+ expiresAt: new Date(Date.now() + expiresInMs),
152
+ ipAddress: request.headers.get('x-forwarded-for') ?? request.headers.get('x-real-ip') ?? null,
153
+ userAgent: request.headers.get('user-agent') ?? null,
154
+ });
155
+ if (hooks?.afterSessionCreated) {
156
+ await hooks.afterSessionCreated({ adapter, session, user });
157
+ }
158
+ // Sign the session cookie
159
+ const cookieName = sessionConfig.cookieName ?? 'cloud_auth_session';
160
+ const cookieSecret = secret;
161
+ if (!cookieSecret) {
162
+ throw new Error('cloudAuth: security.secret is required for cookie signing');
163
+ }
164
+ const signedToken = await signCookie(sessionToken, cookieSecret);
165
+ const cookieHeader = serializeCookie(cookieName, signedToken, {
166
+ maxAge: sessionConfig.expiresIn ?? 30 * 24 * 60 * 60,
167
+ path: '/',
168
+ secure: sessionConfig.secure ?? true,
169
+ httpOnly: sessionConfig.httpOnly ?? true,
170
+ sameSite: sessionConfig.sameSite ?? 'lax',
171
+ });
172
+ return { session, user, cookieHeader };
173
+ }
174
+ /**
175
+ * Get the current session from a request.
176
+ * Validates the session cookie, checks expiry, and returns session with user.
177
+ */
178
+ export async function getSession(config, request) {
179
+ const adapter = config.database;
180
+ const secret = config.security?.secret;
181
+ const sessionConfig = config.session ?? {};
182
+ const cookieName = sessionConfig.cookieName ?? 'cloud_auth_session';
183
+ if (!secret) {
184
+ throw new Error('cloudAuth: security.secret is required');
185
+ }
186
+ const cookieHeader = request.headers.get('cookie');
187
+ if (!cookieHeader)
188
+ return null;
189
+ const cookies = parseCookies(cookieHeader);
190
+ const signedToken = cookies[cookieName];
191
+ if (!signedToken)
192
+ return null;
193
+ const token = await verifyCookie(signedToken, secret);
194
+ if (!token)
195
+ return null;
196
+ const tokenHash = await hashToken(token);
197
+ const sessionWithUser = await adapter.getSessionByTokenHash(tokenHash);
198
+ if (!sessionWithUser)
199
+ return null;
200
+ // Check expiry
201
+ if (sessionWithUser.session.expiresAt < new Date()) {
202
+ await adapter.deleteSession(tokenHash);
203
+ return null;
204
+ }
205
+ // Rolling expiration
206
+ const updateAge = sessionConfig.updateAge;
207
+ if (updateAge && sessionWithUser.session.expiresAt.getTime() - Date.now() < updateAge * 1000) {
208
+ const newExpiresAt = new Date(Date.now() + (sessionConfig.expiresIn ?? 30 * 24 * 60 * 60) * 1000);
209
+ await adapter.updateSession(sessionWithUser.session.id, { expiresAt: newExpiresAt });
210
+ sessionWithUser.session.expiresAt = newExpiresAt;
211
+ }
212
+ return sessionWithUser;
213
+ }
214
+ /**
215
+ * Sign out a user by deleting their session and returning a cleared cookie.
216
+ */
217
+ export async function signOut(config, request, hooks) {
218
+ const adapter = config.database;
219
+ const secret = config.security?.secret;
220
+ const sessionConfig = config.session ?? {};
221
+ const cookieName = sessionConfig.cookieName ?? 'cloud_auth_session';
222
+ if (!secret) {
223
+ throw new Error('cloudAuth: security.secret is required');
224
+ }
225
+ const cookieHeader = request.headers.get('cookie');
226
+ if (cookieHeader) {
227
+ const cookies = parseCookies(cookieHeader);
228
+ const signedToken = cookies[cookieName];
229
+ if (signedToken) {
230
+ const token = await verifyCookie(signedToken, secret);
231
+ if (token) {
232
+ const tokenHash = await hashToken(token);
233
+ const sessionWithUser = await adapter.getSessionByTokenHash(tokenHash);
234
+ if (sessionWithUser && hooks?.beforeLogout) {
235
+ await hooks.beforeLogout({ adapter, session: sessionWithUser.session });
236
+ }
237
+ await adapter.deleteSession(tokenHash);
238
+ if (sessionWithUser && hooks?.afterLogout) {
239
+ await hooks.afterLogout({ adapter, session: sessionWithUser.session });
240
+ }
241
+ }
242
+ }
243
+ }
244
+ return serializeCookie(cookieName, '', {
245
+ maxAge: 0,
246
+ path: '/',
247
+ secure: sessionConfig.secure ?? true,
248
+ httpOnly: sessionConfig.httpOnly ?? true,
249
+ sameSite: sessionConfig.sameSite ?? 'lax',
250
+ });
251
+ }
252
+ // --- Internal helpers ---
253
+ function findProvider(providers, id) {
254
+ const provider = providers.find((p) => p.id === id);
255
+ if (!provider) {
256
+ throw new Error(`Provider "${id}" not found`);
257
+ }
258
+ return provider;
259
+ }
260
+ function buildCallbackUrl(config, providerId) {
261
+ const base = config.baseURL.replace(/\/+$/, '');
262
+ return `${base}/auth/${providerId}/callback`;
263
+ }
264
+ function buildRedirectUri(config, providerId) {
265
+ return buildCallbackUrl(config, providerId);
266
+ }
267
+ function parseCookies(header) {
268
+ const result = {};
269
+ for (const pair of header.split(';')) {
270
+ const idx = pair.indexOf('=');
271
+ if (idx === -1)
272
+ continue;
273
+ const name = pair.slice(0, idx).trim();
274
+ const value = pair.slice(idx + 1).trim();
275
+ if (name)
276
+ result[decodeURIComponent(name)] = decodeURIComponent(value);
277
+ }
278
+ return result;
279
+ }
280
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { AuthProvider } from './provider.js';
2
+ import type { AuthAdapter } from './adapter.js';
3
+ import type { AdditionalFieldsConfig } from './additional-fields.js';
4
+ import type { HooksConfig } from './hooks.js';
5
+ export interface SessionConfig {
6
+ cookieName?: string;
7
+ expiresIn?: number;
8
+ updateAge?: number;
9
+ sameSite?: 'lax' | 'strict' | 'none';
10
+ secure?: boolean;
11
+ httpOnly?: boolean;
12
+ }
13
+ export interface UserConfig {
14
+ additionalFields?: AdditionalFieldsConfig;
15
+ mapProfileToUser?: (profile: import('./types.js').ProviderProfile) => Promise<Record<string, unknown>>;
16
+ }
17
+ export interface AccountLinkingConfig {
18
+ enabled?: boolean;
19
+ trustedProviders?: string[];
20
+ requireVerifiedEmail?: boolean;
21
+ providerTrust?: Record<string, 'high' | 'medium' | 'low'>;
22
+ }
23
+ export interface SecurityConfig {
24
+ storeProviderTokens?: boolean;
25
+ encryptProviderTokens?: boolean;
26
+ pkce?: boolean;
27
+ secret?: string;
28
+ providerHttp?: {
29
+ timeout?: number;
30
+ retries?: number;
31
+ retryDelay?: number;
32
+ };
33
+ }
34
+ export interface AuthConfig {
35
+ appName: string;
36
+ baseURL: string;
37
+ trustedOrigins?: string[];
38
+ providers: AuthProvider[];
39
+ database: AuthAdapter;
40
+ session?: SessionConfig;
41
+ user?: UserConfig;
42
+ accountLinking?: AccountLinkingConfig;
43
+ security?: SecurityConfig;
44
+ hooks?: HooksConfig;
45
+ }
46
+ export interface CloudAuthInstance {
47
+ $Infer: {
48
+ User: import('./types.js').User;
49
+ };
50
+ createAuthUrl(providerId: string, request?: Request): Promise<URL>;
51
+ handleCallback(providerId: string, request: Request): Promise<import('./auth.js').AuthResponse>;
52
+ getSession(request: Request): Promise<import('./types.js').SessionWithUser | null>;
53
+ signOut(request: Request): Promise<string>;
54
+ }
55
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;IACpC,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,gBAAgB,CAAC,EAAE,sBAAsB,CAAA;IACzC,gBAAgB,CAAC,EAAE,CACjB,OAAO,EAAE,OAAO,YAAY,EAAE,eAAe,KAC1C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACtC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAA;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC,CAAA;CAC1D;AAED,MAAM,WAAW,cAAc;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,YAAY,CAAC,EAAE;QACb,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,UAAU,CAAC,EAAE,MAAM,CAAA;KACpB,CAAA;CACF;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,SAAS,EAAE,YAAY,EAAE,CAAA;IACzB,QAAQ,EAAE,WAAW,CAAA;IACrB,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,cAAc,CAAC,EAAE,oBAAoB,CAAA;IACrC,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,KAAK,CAAC,EAAE,WAAW,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE;QACN,IAAI,EAAE,OAAO,YAAY,EAAE,IAAI,CAAA;KAChC,CAAA;IACD,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IAClE,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,WAAW,EAAE,YAAY,CAAC,CAAA;IAC/F,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC,CAAA;IAClF,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CAC3C"}
package/dist/config.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ export interface CookieOptions {
2
+ maxAge?: number;
3
+ expires?: Date;
4
+ path?: string;
5
+ domain?: string;
6
+ secure?: boolean;
7
+ httpOnly?: boolean;
8
+ sameSite?: 'lax' | 'strict' | 'none';
9
+ }
10
+ /**
11
+ * Serialize a cookie name-value pair into a Set-Cookie header string.
12
+ */
13
+ export declare function serializeCookie(name: string, value: string, options?: CookieOptions): string;
14
+ /**
15
+ * Parse a Cookie header string into a key-value record.
16
+ * Ignores known cookie attribute names (Path, Domain, Secure, etc.).
17
+ */
18
+ export declare function parseCookie(header: string): Record<string, string>;
19
+ /**
20
+ * Sign a cookie value using HMAC-SHA256.
21
+ * Returns a string in the format: `value.base64url-signature`.
22
+ */
23
+ export declare function signCookie(value: string, secret: string): Promise<string>;
24
+ /**
25
+ * Verify a signed cookie value.
26
+ * Returns the original value if the signature is valid, or null if tampered.
27
+ */
28
+ export declare function verifyCookie(signed: string, secret: string): Promise<string | null>;
29
+ //# sourceMappingURL=cookies.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookies.d.ts","sourceRoot":"","sources":["../src/cookies.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,IAAI,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAA;CACrC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM,CA0B5F;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA4BlE;AAoBD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAQ/E;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASzF"}
@@ -0,0 +1,98 @@
1
+ import { constantTimeEqual } from './crypto.js';
2
+ /**
3
+ * Serialize a cookie name-value pair into a Set-Cookie header string.
4
+ */
5
+ export function serializeCookie(name, value, options) {
6
+ let cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
7
+ if (options?.maxAge !== undefined) {
8
+ cookie += `; Max-Age=${String(options.maxAge)}`;
9
+ }
10
+ if (options?.expires) {
11
+ cookie += `; Expires=${options.expires.toUTCString()}`;
12
+ }
13
+ if (options?.path) {
14
+ cookie += `; Path=${options.path}`;
15
+ }
16
+ if (options?.domain) {
17
+ cookie += `; Domain=${options.domain}`;
18
+ }
19
+ if (options?.secure) {
20
+ cookie += `; Secure`;
21
+ }
22
+ if (options?.httpOnly) {
23
+ cookie += `; HttpOnly`;
24
+ }
25
+ if (options?.sameSite) {
26
+ cookie += `; SameSite=${options.sameSite}`;
27
+ }
28
+ return cookie;
29
+ }
30
+ /**
31
+ * Parse a Cookie header string into a key-value record.
32
+ * Ignores known cookie attribute names (Path, Domain, Secure, etc.).
33
+ */
34
+ export function parseCookie(header) {
35
+ const result = {};
36
+ const knownAttributes = new Set([
37
+ 'path',
38
+ 'domain',
39
+ 'secure',
40
+ 'httponly',
41
+ 'samesite',
42
+ 'max-age',
43
+ 'expires',
44
+ ]);
45
+ for (const pair of header.split(';')) {
46
+ const separatorIndex = pair.indexOf('=');
47
+ if (separatorIndex === -1)
48
+ continue;
49
+ const rawName = pair.slice(0, separatorIndex).trim();
50
+ const rawValue = pair.slice(separatorIndex + 1).trim();
51
+ if (!rawName)
52
+ continue;
53
+ const name = decodeURIComponent(rawName);
54
+ // Skip known cookie attribute names
55
+ if (knownAttributes.has(name.toLowerCase()))
56
+ continue;
57
+ result[name] = decodeURIComponent(rawValue);
58
+ }
59
+ return result;
60
+ }
61
+ // Cache HMAC keys per secret to avoid re-importing on every sign/verify
62
+ const hmacKeyCache = new Map();
63
+ async function getHmacKey(secret) {
64
+ const cached = hmacKeyCache.get(secret);
65
+ if (cached)
66
+ return cached;
67
+ const keyPromise = crypto.subtle.importKey('raw', new TextEncoder().encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify']);
68
+ hmacKeyCache.set(secret, keyPromise);
69
+ return keyPromise;
70
+ }
71
+ /**
72
+ * Sign a cookie value using HMAC-SHA256.
73
+ * Returns a string in the format: `value.base64url-signature`.
74
+ */
75
+ export async function signCookie(value, secret) {
76
+ const key = await getHmacKey(secret);
77
+ const signature = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(value));
78
+ const encoded = btoa(String.fromCharCode(...new Uint8Array(signature)))
79
+ .replace(/\+/g, '-')
80
+ .replace(/\//g, '_')
81
+ .replace(/=+$/, '');
82
+ return `${value}.${encoded}`;
83
+ }
84
+ /**
85
+ * Verify a signed cookie value.
86
+ * Returns the original value if the signature is valid, or null if tampered.
87
+ */
88
+ export async function verifyCookie(signed, secret) {
89
+ const lastDot = signed.lastIndexOf('.');
90
+ if (lastDot === -1)
91
+ return null;
92
+ const value = signed.slice(0, lastDot);
93
+ if (!value)
94
+ return null;
95
+ const expected = await signCookie(value, secret);
96
+ return constantTimeEqual(signed, expected) ? value : null;
97
+ }
98
+ //# sourceMappingURL=cookies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookies.js","sourceRoot":"","sources":["../src/cookies.ts"],"names":[],"mappings":"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"}