@alliance-droid/svelte-auth-core 1.0.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 (178) hide show
  1. package/dist/adapter-context.d.ts +19 -0
  2. package/dist/adapter-context.d.ts.map +1 -0
  3. package/dist/adapter-context.js +68 -0
  4. package/dist/adapter-context.js.map +1 -0
  5. package/dist/adapters/__tests__/adapter-tests.d.ts +7 -0
  6. package/dist/adapters/__tests__/adapter-tests.d.ts.map +1 -0
  7. package/dist/adapters/__tests__/adapter-tests.js +206 -0
  8. package/dist/adapters/__tests__/adapter-tests.js.map +1 -0
  9. package/dist/adapters/adapter.d.ts +60 -0
  10. package/dist/adapters/adapter.d.ts.map +1 -0
  11. package/dist/adapters/adapter.js +2 -0
  12. package/dist/adapters/adapter.js.map +1 -0
  13. package/dist/adapters/filesystem-adapter.d.ts +26 -0
  14. package/dist/adapters/filesystem-adapter.d.ts.map +1 -0
  15. package/dist/adapters/filesystem-adapter.js +148 -0
  16. package/dist/adapters/filesystem-adapter.js.map +1 -0
  17. package/dist/adapters/index.d.ts +6 -0
  18. package/dist/adapters/index.d.ts.map +1 -0
  19. package/dist/adapters/index.js +5 -0
  20. package/dist/adapters/index.js.map +1 -0
  21. package/dist/adapters/mongodb-adapter.d.ts +27 -0
  22. package/dist/adapters/mongodb-adapter.d.ts.map +1 -0
  23. package/dist/adapters/mongodb-adapter.js +213 -0
  24. package/dist/adapters/mongodb-adapter.js.map +1 -0
  25. package/dist/adapters/postgres-adapter.d.ts +30 -0
  26. package/dist/adapters/postgres-adapter.d.ts.map +1 -0
  27. package/dist/adapters/postgres-adapter.js +237 -0
  28. package/dist/adapters/postgres-adapter.js.map +1 -0
  29. package/dist/adapters/sqlite-adapter.d.ts +26 -0
  30. package/dist/adapters/sqlite-adapter.d.ts.map +1 -0
  31. package/dist/adapters/sqlite-adapter.js +261 -0
  32. package/dist/adapters/sqlite-adapter.js.map +1 -0
  33. package/dist/auth.d.ts +48 -0
  34. package/dist/auth.d.ts.map +1 -0
  35. package/dist/auth.js +205 -0
  36. package/dist/auth.js.map +1 -0
  37. package/dist/client-jwt.d.ts +30 -0
  38. package/dist/client-jwt.d.ts.map +1 -0
  39. package/dist/client-jwt.js +57 -0
  40. package/dist/client-jwt.js.map +1 -0
  41. package/dist/client-store.d.ts +31 -0
  42. package/dist/client-store.d.ts.map +1 -0
  43. package/dist/client-store.js +122 -0
  44. package/dist/client-store.js.map +1 -0
  45. package/dist/cors.d.ts +48 -0
  46. package/dist/cors.d.ts.map +1 -0
  47. package/dist/cors.js +88 -0
  48. package/dist/cors.js.map +1 -0
  49. package/dist/csrf.d.ts +57 -0
  50. package/dist/csrf.d.ts.map +1 -0
  51. package/dist/csrf.js +95 -0
  52. package/dist/csrf.js.map +1 -0
  53. package/dist/db.d.ts +22 -0
  54. package/dist/db.d.ts.map +1 -0
  55. package/dist/db.js +43 -0
  56. package/dist/db.js.map +1 -0
  57. package/dist/index.d.ts +35 -0
  58. package/dist/index.d.ts.map +1 -0
  59. package/dist/index.js +36 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/input-validation.d.ts +78 -0
  62. package/dist/input-validation.d.ts.map +1 -0
  63. package/dist/input-validation.js +238 -0
  64. package/dist/input-validation.js.map +1 -0
  65. package/dist/oauth-callback.d.ts +31 -0
  66. package/dist/oauth-callback.d.ts.map +1 -0
  67. package/dist/oauth-callback.js +254 -0
  68. package/dist/oauth-callback.js.map +1 -0
  69. package/dist/oauth-providers.d.ts +92 -0
  70. package/dist/oauth-providers.d.ts.map +1 -0
  71. package/dist/oauth-providers.js +213 -0
  72. package/dist/oauth-providers.js.map +1 -0
  73. package/dist/oauth-types.d.ts +77 -0
  74. package/dist/oauth-types.d.ts.map +1 -0
  75. package/dist/oauth-types.js +2 -0
  76. package/dist/oauth-types.js.map +1 -0
  77. package/dist/password.d.ts +31 -0
  78. package/dist/password.d.ts.map +1 -0
  79. package/dist/password.js +54 -0
  80. package/dist/password.js.map +1 -0
  81. package/dist/providers/github-oauth.d.ts +58 -0
  82. package/dist/providers/github-oauth.d.ts.map +1 -0
  83. package/dist/providers/github-oauth.js +230 -0
  84. package/dist/providers/github-oauth.js.map +1 -0
  85. package/dist/providers/google-oauth.d.ts +46 -0
  86. package/dist/providers/google-oauth.d.ts.map +1 -0
  87. package/dist/providers/google-oauth.js +177 -0
  88. package/dist/providers/google-oauth.js.map +1 -0
  89. package/dist/providers/oidc-oauth.d.ts +85 -0
  90. package/dist/providers/oidc-oauth.d.ts.map +1 -0
  91. package/dist/providers/oidc-oauth.js +301 -0
  92. package/dist/providers/oidc-oauth.js.map +1 -0
  93. package/dist/rate-limit.d.ts +36 -0
  94. package/dist/rate-limit.d.ts.map +1 -0
  95. package/dist/rate-limit.js +88 -0
  96. package/dist/rate-limit.js.map +1 -0
  97. package/dist/rate-limiting.d.ts +113 -0
  98. package/dist/rate-limiting.d.ts.map +1 -0
  99. package/dist/rate-limiting.js +221 -0
  100. package/dist/rate-limiting.js.map +1 -0
  101. package/dist/security-headers.d.ts +54 -0
  102. package/dist/security-headers.d.ts.map +1 -0
  103. package/dist/security-headers.js +123 -0
  104. package/dist/security-headers.js.map +1 -0
  105. package/dist/session.d.ts +13 -0
  106. package/dist/session.d.ts.map +1 -0
  107. package/dist/session.js +33 -0
  108. package/dist/session.js.map +1 -0
  109. package/dist/sql-injection-prevention.d.ts +94 -0
  110. package/dist/sql-injection-prevention.d.ts.map +1 -0
  111. package/dist/sql-injection-prevention.js +222 -0
  112. package/dist/sql-injection-prevention.js.map +1 -0
  113. package/dist/token.d.ts +22 -0
  114. package/dist/token.d.ts.map +1 -0
  115. package/dist/token.js +31 -0
  116. package/dist/token.js.map +1 -0
  117. package/dist/types.d.ts +81 -0
  118. package/dist/types.d.ts.map +1 -0
  119. package/dist/types.js +2 -0
  120. package/dist/types.js.map +1 -0
  121. package/dist/user.d.ts +33 -0
  122. package/dist/user.d.ts.map +1 -0
  123. package/dist/user.js +144 -0
  124. package/dist/user.js.map +1 -0
  125. package/package.json +48 -0
  126. package/src/adapter-context.ts +72 -0
  127. package/src/adapters/__tests__/adapter-tests.ts +254 -0
  128. package/src/adapters/__tests__/filesystem-adapter.test.ts +48 -0
  129. package/src/adapters/__tests__/mongodb-adapter.test.ts +64 -0
  130. package/src/adapters/__tests__/postgres-adapter.test.ts +62 -0
  131. package/src/adapters/__tests__/sqlite-adapter.test.ts +103 -0
  132. package/src/adapters/__tests__/test-fs-adapter.json +4 -0
  133. package/src/adapters/adapter.ts +72 -0
  134. package/src/adapters/filesystem-adapter.ts +153 -0
  135. package/src/adapters/index.ts +5 -0
  136. package/src/adapters/mongodb-adapter.ts +208 -0
  137. package/src/adapters/postgres-adapter.ts +261 -0
  138. package/src/adapters/sqlite-adapter.ts +284 -0
  139. package/src/auth.ts +239 -0
  140. package/src/client-jwt.test.ts +137 -0
  141. package/src/client-jwt.ts +67 -0
  142. package/src/client-store.test.ts +149 -0
  143. package/src/client-store.ts +144 -0
  144. package/src/cors.test.ts +175 -0
  145. package/src/cors.ts +115 -0
  146. package/src/csrf.test.ts +226 -0
  147. package/src/csrf.ts +126 -0
  148. package/src/db.ts +57 -0
  149. package/src/index.ts +143 -0
  150. package/src/input-validation.test.ts +347 -0
  151. package/src/input-validation.ts +307 -0
  152. package/src/integration.test.ts +322 -0
  153. package/src/oauth-callback.test.ts +282 -0
  154. package/src/oauth-callback.ts +323 -0
  155. package/src/oauth-providers.ts +232 -0
  156. package/src/oauth-types.ts +82 -0
  157. package/src/password.test.ts +89 -0
  158. package/src/password.ts +62 -0
  159. package/src/providers/github-oauth.test.ts +290 -0
  160. package/src/providers/github-oauth.ts +226 -0
  161. package/src/providers/google-oauth.test.ts +240 -0
  162. package/src/providers/google-oauth.ts +166 -0
  163. package/src/providers/oidc-oauth.test.ts +367 -0
  164. package/src/providers/oidc-oauth.ts +302 -0
  165. package/src/rate-limit.test.ts +308 -0
  166. package/src/rate-limit.ts +118 -0
  167. package/src/rate-limiting.test.ts +390 -0
  168. package/src/rate-limiting.ts +275 -0
  169. package/src/security-headers.test.ts +242 -0
  170. package/src/security-headers.ts +160 -0
  171. package/src/security-penetration.test.ts +705 -0
  172. package/src/session.ts +42 -0
  173. package/src/sql-injection-prevention.test.ts +337 -0
  174. package/src/sql-injection-prevention.ts +272 -0
  175. package/src/token.test.ts +67 -0
  176. package/src/token.ts +34 -0
  177. package/src/types.ts +87 -0
  178. package/src/user.ts +165 -0
@@ -0,0 +1,226 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import {
3
+ generateCsrfToken,
4
+ createCsrfToken,
5
+ validateCsrfToken,
6
+ revokeCsrfToken,
7
+ cleanupExpiredCsrfTokens,
8
+ getCsrfTokenStats,
9
+ csrfTokenStore
10
+ } from './csrf';
11
+
12
+ describe('CSRF Token Utilities', () => {
13
+ beforeEach(() => {
14
+ // Clear token store before each test
15
+ csrfTokenStore.tokens.clear();
16
+ });
17
+
18
+ describe('generateCsrfToken', () => {
19
+ it('should generate a random token', () => {
20
+ const token1 = generateCsrfToken();
21
+ const token2 = generateCsrfToken();
22
+
23
+ expect(token1).toBeTruthy();
24
+ expect(token2).toBeTruthy();
25
+ expect(token1).not.toBe(token2);
26
+ });
27
+
28
+ it('should generate tokens in base64url format', () => {
29
+ const token = generateCsrfToken();
30
+ // Base64url contains A-Z, a-z, 0-9, -, _
31
+ expect(token).toMatch(/^[A-Za-z0-9_-]+$/);
32
+ });
33
+
34
+ it('should generate tokens of consistent length', () => {
35
+ const tokens = Array.from({ length: 10 }, () => generateCsrfToken());
36
+ const lengths = tokens.map((t) => t.length);
37
+ const firstLength = lengths[0];
38
+
39
+ expect(lengths.every((l) => l === firstLength)).toBe(true);
40
+ });
41
+ });
42
+
43
+ describe('createCsrfToken', () => {
44
+ it('should create and store a token for a session', () => {
45
+ const sessionId = 'session-123';
46
+ const token = createCsrfToken(sessionId);
47
+
48
+ expect(token).toBeTruthy();
49
+ expect(csrfTokenStore.tokens.has(sessionId)).toBe(true);
50
+ });
51
+
52
+ it('should set expiry time correctly', () => {
53
+ const sessionId = 'session-456';
54
+ const beforeCreation = Date.now();
55
+ createCsrfToken(sessionId, 30); // 30 minutes
56
+ const afterCreation = Date.now();
57
+
58
+ const stored = csrfTokenStore.tokens.get(sessionId);
59
+ expect(stored).toBeTruthy();
60
+ expect(stored!.expiresAt).toBeGreaterThanOrEqual(beforeCreation + 30 * 60 * 1000);
61
+ expect(stored!.expiresAt).toBeLessThanOrEqual(afterCreation + 30 * 60 * 1000);
62
+ });
63
+
64
+ it('should use default expiry of 60 minutes', () => {
65
+ const sessionId = 'session-789';
66
+ const beforeCreation = Date.now();
67
+ const token = createCsrfToken(sessionId);
68
+ const afterCreation = Date.now();
69
+
70
+ const stored = csrfTokenStore.tokens.get(sessionId);
71
+ expect(stored!.expiresAt).toBeGreaterThanOrEqual(beforeCreation + 60 * 60 * 1000);
72
+ expect(stored!.expiresAt).toBeLessThanOrEqual(afterCreation + 60 * 60 * 1000);
73
+ });
74
+
75
+ it('should store creation timestamp', () => {
76
+ const sessionId = 'session-abc';
77
+ const beforeCreation = Date.now();
78
+ createCsrfToken(sessionId);
79
+ const afterCreation = Date.now();
80
+
81
+ const stored = csrfTokenStore.tokens.get(sessionId);
82
+ expect(stored!.createdAt).toBeGreaterThanOrEqual(beforeCreation);
83
+ expect(stored!.createdAt).toBeLessThanOrEqual(afterCreation);
84
+ });
85
+ });
86
+
87
+ describe('validateCsrfToken', () => {
88
+ it('should validate a correct token', () => {
89
+ const sessionId = 'session-valid';
90
+ const token = createCsrfToken(sessionId);
91
+
92
+ const isValid = validateCsrfToken(sessionId, token);
93
+ expect(isValid).toBe(true);
94
+ });
95
+
96
+ it('should reject an incorrect token', () => {
97
+ const sessionId = 'session-invalid';
98
+ createCsrfToken(sessionId);
99
+
100
+ const isValid = validateCsrfToken(sessionId, 'wrong-token');
101
+ expect(isValid).toBe(false);
102
+ });
103
+
104
+ it('should reject token for non-existent session', () => {
105
+ const isValid = validateCsrfToken('non-existent-session', 'some-token');
106
+ expect(isValid).toBe(false);
107
+ });
108
+
109
+ it('should reject expired tokens', async () => {
110
+ const sessionId = 'session-expired';
111
+ // Create token that expires in 1 millisecond
112
+ const token = createCsrfToken(sessionId, 0.00001);
113
+
114
+ // Wait a bit to ensure expiry
115
+ await new Promise((resolve) => setTimeout(resolve, 100));
116
+
117
+ const isValid = validateCsrfToken(sessionId, token);
118
+ expect(isValid).toBe(false);
119
+ });
120
+
121
+ it('should clean up expired token from store', async () => {
122
+ const sessionId = 'session-cleanup';
123
+ createCsrfToken(sessionId, 0.00001);
124
+
125
+ await new Promise((resolve) => setTimeout(resolve, 100));
126
+
127
+ validateCsrfToken(sessionId, generateCsrfToken());
128
+
129
+ // Token should be deleted from store
130
+ expect(csrfTokenStore.tokens.has(sessionId)).toBe(false);
131
+ });
132
+
133
+ it('should perform timing-safe comparison', () => {
134
+ const sessionId = 'session-timing';
135
+ const token = createCsrfToken(sessionId);
136
+
137
+ // Test with same length but different token
138
+ const invalidToken = token.split('').reverse().join('');
139
+ const isValid = validateCsrfToken(sessionId, invalidToken);
140
+
141
+ expect(isValid).toBe(false);
142
+ });
143
+
144
+ it('should reject tokens of different length', () => {
145
+ const sessionId = 'session-length';
146
+ createCsrfToken(sessionId);
147
+
148
+ const isValid = validateCsrfToken(sessionId, 'short');
149
+ expect(isValid).toBe(false);
150
+ });
151
+ });
152
+
153
+ describe('revokeCsrfToken', () => {
154
+ it('should remove token from store', () => {
155
+ const sessionId = 'session-revoke';
156
+ createCsrfToken(sessionId);
157
+
158
+ expect(csrfTokenStore.tokens.has(sessionId)).toBe(true);
159
+
160
+ revokeCsrfToken(sessionId);
161
+
162
+ expect(csrfTokenStore.tokens.has(sessionId)).toBe(false);
163
+ });
164
+
165
+ it('should handle revoking non-existent token gracefully', () => {
166
+ expect(() => revokeCsrfToken('non-existent')).not.toThrow();
167
+ });
168
+
169
+ it('should prevent validation after revocation', () => {
170
+ const sessionId = 'session-revoke-validate';
171
+ const token = createCsrfToken(sessionId);
172
+
173
+ revokeCsrfToken(sessionId);
174
+
175
+ const isValid = validateCsrfToken(sessionId, token);
176
+ expect(isValid).toBe(false);
177
+ });
178
+ });
179
+
180
+ describe('cleanupExpiredCsrfTokens', () => {
181
+ it('should remove expired tokens', async () => {
182
+ createCsrfToken('session-1', 0.00001);
183
+ createCsrfToken('session-2', 60); // Valid
184
+
185
+ await new Promise((resolve) => setTimeout(resolve, 100));
186
+
187
+ expect(csrfTokenStore.tokens.size).toBe(2);
188
+
189
+ cleanupExpiredCsrfTokens();
190
+
191
+ expect(csrfTokenStore.tokens.size).toBe(1);
192
+ expect(csrfTokenStore.tokens.has('session-2')).toBe(true);
193
+ });
194
+
195
+ it('should keep valid tokens', () => {
196
+ createCsrfToken('session-a', 60);
197
+ createCsrfToken('session-b', 60);
198
+ createCsrfToken('session-c', 60);
199
+
200
+ cleanupExpiredCsrfTokens();
201
+
202
+ expect(csrfTokenStore.tokens.size).toBe(3);
203
+ });
204
+
205
+ it('should handle empty token store', () => {
206
+ expect(() => cleanupExpiredCsrfTokens()).not.toThrow();
207
+ expect(csrfTokenStore.tokens.size).toBe(0);
208
+ });
209
+ });
210
+
211
+ describe('getCsrfTokenStats', () => {
212
+ it('should return token count', () => {
213
+ createCsrfToken('session-1');
214
+ createCsrfToken('session-2');
215
+ createCsrfToken('session-3');
216
+
217
+ const stats = getCsrfTokenStats();
218
+ expect(stats.tokenCount).toBe(3);
219
+ });
220
+
221
+ it('should return zero for empty store', () => {
222
+ const stats = getCsrfTokenStats();
223
+ expect(stats.tokenCount).toBe(0);
224
+ });
225
+ });
226
+ });
package/src/csrf.ts ADDED
@@ -0,0 +1,126 @@
1
+ import { randomBytes, timingSafeEqual } from 'crypto';
2
+
3
+ /**
4
+ * CSRF Token storage interface
5
+ * Stores CSRF tokens associated with sessions
6
+ */
7
+ export interface CsrfTokenStore {
8
+ tokens: Map<string, CsrfTokenData>;
9
+ }
10
+
11
+ /**
12
+ * CSRF Token data with expiry
13
+ */
14
+ export interface CsrfTokenData {
15
+ token: string;
16
+ expiresAt: number;
17
+ createdAt: number;
18
+ }
19
+
20
+ /**
21
+ * In-memory CSRF token store
22
+ */
23
+ export const csrfTokenStore: CsrfTokenStore = {
24
+ tokens: new Map()
25
+ };
26
+
27
+ /**
28
+ * Generate a cryptographically secure CSRF token
29
+ * @returns CSRF token (base64 encoded for safe transmission)
30
+ */
31
+ export function generateCsrfToken(): string {
32
+ return randomBytes(32).toString('base64url');
33
+ }
34
+
35
+ /**
36
+ * Generate CSRF token for a session
37
+ * @param sessionId - Session ID to store the token under
38
+ * @param expiryMinutes - Token expiry time in minutes (default: 60)
39
+ * @returns CSRF token
40
+ */
41
+ export function createCsrfToken(sessionId: string, expiryMinutes: number = 60): string {
42
+ const token = generateCsrfToken();
43
+ const expiresAt = Date.now() + expiryMinutes * 60 * 1000;
44
+
45
+ csrfTokenStore.tokens.set(sessionId, {
46
+ token,
47
+ expiresAt,
48
+ createdAt: Date.now()
49
+ });
50
+
51
+ return token;
52
+ }
53
+
54
+ /**
55
+ * Validate a CSRF token against stored token for session
56
+ * Uses timing-safe comparison to prevent timing attacks
57
+ * @param sessionId - Session ID
58
+ * @param providedToken - Token to validate (from form/header)
59
+ * @returns True if valid, false otherwise
60
+ */
61
+ export function validateCsrfToken(sessionId: string, providedToken: string): boolean {
62
+ const stored = csrfTokenStore.tokens.get(sessionId);
63
+
64
+ if (!stored) {
65
+ return false;
66
+ }
67
+
68
+ // Check if token has expired
69
+ if (Date.now() > stored.expiresAt) {
70
+ csrfTokenStore.tokens.delete(sessionId);
71
+ return false;
72
+ }
73
+
74
+ try {
75
+ // Use timing-safe comparison to prevent timing attacks
76
+ const storedBuffer = Buffer.from(stored.token);
77
+ const providedBuffer = Buffer.from(providedToken);
78
+
79
+ // Check lengths match before comparison
80
+ if (storedBuffer.length !== providedBuffer.length) {
81
+ return false;
82
+ }
83
+
84
+ return timingSafeEqual(storedBuffer, providedBuffer);
85
+ } catch {
86
+ // If comparison fails, token is invalid
87
+ return false;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Revoke a CSRF token
93
+ * @param sessionId - Session ID
94
+ */
95
+ export function revokeCsrfToken(sessionId: string): void {
96
+ csrfTokenStore.tokens.delete(sessionId);
97
+ }
98
+
99
+ /**
100
+ * Clean up expired CSRF tokens
101
+ * Should be run periodically
102
+ */
103
+ export function cleanupExpiredCsrfTokens(): void {
104
+ const now = Date.now();
105
+ const expiredSessions: string[] = [];
106
+
107
+ csrfTokenStore.tokens.forEach((data, sessionId) => {
108
+ if (now > data.expiresAt) {
109
+ expiredSessions.push(sessionId);
110
+ }
111
+ });
112
+
113
+ expiredSessions.forEach((sessionId) => {
114
+ csrfTokenStore.tokens.delete(sessionId);
115
+ });
116
+ }
117
+
118
+ /**
119
+ * Get token statistics (for debugging/monitoring)
120
+ * @returns Number of stored tokens
121
+ */
122
+ export function getCsrfTokenStats(): { tokenCount: number } {
123
+ return {
124
+ tokenCount: csrfTokenStore.tokens.size
125
+ };
126
+ }
package/src/db.ts ADDED
@@ -0,0 +1,57 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import type { User } from './types';
4
+ import type { OAuthUser, OAuthSession } from './oauth-types';
5
+
6
+ interface DatabaseStore {
7
+ users: Record<string, User>;
8
+ sessions: Record<string, any>;
9
+ oauthUsers?: Record<string, OAuthUser>;
10
+ oauthSessions?: Record<string, OAuthSession>;
11
+ }
12
+
13
+ let dbPath: string = '';
14
+ let store: DatabaseStore | null = null;
15
+
16
+ /**
17
+ * Get or initialize the database
18
+ */
19
+ export function getDatabase(customDbPath?: string): DatabaseStore {
20
+ if (store) {
21
+ return store;
22
+ }
23
+
24
+ dbPath = customDbPath || path.join(process.cwd(), 'auth.json');
25
+
26
+ if (fs.existsSync(dbPath)) {
27
+ const data = fs.readFileSync(dbPath, 'utf-8');
28
+ store = JSON.parse(data) as DatabaseStore;
29
+ } else {
30
+ store = {
31
+ users: {},
32
+ sessions: {}
33
+ };
34
+ saveDatabase();
35
+ }
36
+
37
+ return store as DatabaseStore;
38
+ }
39
+
40
+ /**
41
+ * Save database to disk
42
+ */
43
+ export function saveDatabase(): void {
44
+ if (store && dbPath) {
45
+ fs.writeFileSync(dbPath, JSON.stringify(store, null, 2), 'utf-8');
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Close database connection
51
+ */
52
+ export function closeDatabase(): void {
53
+ if (store) {
54
+ saveDatabase();
55
+ store = null;
56
+ }
57
+ }
package/src/index.ts ADDED
@@ -0,0 +1,143 @@
1
+ // Types
2
+ export type { User, RegisterInput, LoginInput, Session, AuthResponse, PasswordResetRequest, PasswordReset } from './types';
3
+
4
+ // Database adapters
5
+ export type { DatabaseAdapter } from './adapters/adapter';
6
+ export { FileSystemAdapter, PostgresAdapter, MongoDBAdapter, SqliteAdapter } from './adapters';
7
+ export { initializeAdapter, initializeDefaultAdapter, getAdapter, closeAdapter } from './adapter-context';
8
+
9
+ // Legacy database (kept for backward compatibility)
10
+ export { getDatabase, closeDatabase } from './db';
11
+
12
+ // Password utilities
13
+ export { hashPassword, verifyPassword, validatePasswordStrength, isValidEmail } from './password';
14
+
15
+ // Token utilities
16
+ export { generateToken, generateId, getTokenExpiry, isTokenExpired } from './token';
17
+
18
+ // CSRF protection
19
+ export {
20
+ generateCsrfToken,
21
+ createCsrfToken,
22
+ validateCsrfToken,
23
+ revokeCsrfToken,
24
+ cleanupExpiredCsrfTokens,
25
+ getCsrfTokenStats
26
+ } from './csrf';
27
+ export type { CsrfTokenStore, CsrfTokenData } from './csrf';
28
+
29
+ // CORS configuration
30
+ export {
31
+ isOriginAllowed,
32
+ generateCorsHeaders,
33
+ isPreflightRequest,
34
+ validateCorsRequest,
35
+ defaultCorsConfig
36
+ } from './cors';
37
+ export type { CorsConfig } from './cors';
38
+
39
+ // Security headers
40
+ export {
41
+ generateSecurityHeaders,
42
+ validateCSP,
43
+ getDevelopmentCSP,
44
+ getProductionCSP,
45
+ defaultSecurityHeadersConfig,
46
+ securityLevels
47
+ } from './security-headers';
48
+ export type { SecurityHeadersConfig } from './security-headers';
49
+
50
+ // Input validation and sanitization
51
+ export {
52
+ sanitizeString,
53
+ validateEmail,
54
+ validatePassword,
55
+ validateUsername,
56
+ validateUrl,
57
+ validateNumber,
58
+ validateUuid,
59
+ escapeHtml,
60
+ validateObject
61
+ } from './input-validation';
62
+ export type { ValidationResult } from './input-validation';
63
+
64
+ // SQL injection prevention
65
+ export {
66
+ isSafePropertyName,
67
+ getSafeProperty,
68
+ safeFilter,
69
+ safeSearch,
70
+ sanitizeForLikeQuery,
71
+ prepareDatabaseValue,
72
+ validateDatabaseQuery,
73
+ databaseSecurityGuides,
74
+ getParameterizedQueryExample
75
+ } from './sql-injection-prevention';
76
+ export type { SafeQueryParams } from './sql-injection-prevention';
77
+
78
+ // Rate limiting
79
+ export {
80
+ RateLimiter,
81
+ rateLimitPresets,
82
+ getClientIdentifier,
83
+ getRateLimitHeaders
84
+ } from './rate-limiting';
85
+ export type { RateLimitConfig, RateLimitAttempt } from './rate-limiting';
86
+
87
+ // User operations
88
+ export { registerUser, getUserById, getUserByEmail, verifyUserEmail, setPasswordResetToken, updateUserPassword } from './user';
89
+
90
+ // Authentication
91
+ export {
92
+ loginUser,
93
+ createSession,
94
+ getSession,
95
+ destroySession,
96
+ requestPasswordReset,
97
+ verifyPasswordResetToken,
98
+ resetPassword,
99
+ verifyEmailToken,
100
+ completeEmailVerification,
101
+ cleanupExpiredSessions
102
+ } from './auth';
103
+
104
+ // Client-side stores and utilities (Svelte)
105
+ export { auth, user, isAuthenticated, isLoading, authError, accessToken } from './client-store';
106
+ export type { User as ClientUser, AuthState } from './client-store';
107
+ export { decodeToken, isTokenExpired as isTokenExpiredClient, getTokenTimeRemaining, createAuthHeader, extractToken } from './client-jwt';
108
+ export type { TokenPayload } from './client-jwt';
109
+
110
+ // OAuth/OIDC Types
111
+ export type {
112
+ OAuthProviderConfig,
113
+ OAuthUserProfile,
114
+ OAuthTokenResponse,
115
+ OAuthCodeResponse,
116
+ OAuthSession,
117
+ OAuthUser,
118
+ OAuthCallbackResponse
119
+ } from './oauth-types';
120
+
121
+ // OAuth Providers
122
+ export { OAuthProviderFactory, OAuthProfileParser, OAuthTokenManager, OAuthConfigStore } from './oauth-providers';
123
+
124
+ // OAuth Callbacks and Session Management
125
+ export {
126
+ handleOAuthCallback,
127
+ getOAuthSession,
128
+ destroyOAuthSession,
129
+ refreshOAuthToken,
130
+ getOAuthUser,
131
+ updateOAuthUserProfile,
132
+ cleanupExpiredOAuthSessions
133
+ } from './oauth-callback';
134
+
135
+ // OAuth Specific Providers
136
+ export { GoogleOAuthProvider } from './providers/google-oauth';
137
+ export type { GoogleOAuthConfig } from './providers/google-oauth';
138
+
139
+ export { GitHubOAuthProvider } from './providers/github-oauth';
140
+ export type { GitHubOAuthConfig } from './providers/github-oauth';
141
+
142
+ export { OIDCOAuthProvider } from './providers/oidc-oauth';
143
+ export type { OIDCProviderConfig } from './providers/oidc-oauth';