@lenne.tech/nest-server 11.6.1 → 11.7.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.
- package/dist/config.env.js +132 -0
- package/dist/config.env.js.map +1 -1
- package/dist/core/common/decorators/graphql-populate.decorator.d.ts +2 -2
- package/dist/core/common/decorators/restricted.decorator.d.ts +1 -0
- package/dist/core/common/decorators/restricted.decorator.js +1 -1
- package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
- package/dist/core/common/helpers/filter.helper.d.ts +9 -9
- package/dist/core/common/helpers/filter.helper.js +2 -4
- package/dist/core/common/helpers/filter.helper.js.map +1 -1
- package/dist/core/common/helpers/gridfs.helper.js +3 -3
- package/dist/core/common/helpers/gridfs.helper.js.map +1 -1
- package/dist/core/common/helpers/input.helper.d.ts +1 -0
- package/dist/core/common/helpers/input.helper.js +1 -1
- package/dist/core/common/helpers/input.helper.js.map +1 -1
- package/dist/core/common/interfaces/server-options.interface.d.ts +51 -0
- package/dist/core/common/services/crud.service.d.ts +16 -16
- package/dist/core/common/services/crud.service.js +1 -1
- package/dist/core/common/services/crud.service.js.map +1 -1
- package/dist/core/modules/auth/auth-guard-strategy.enum.d.ts +1 -0
- package/dist/core/modules/auth/auth-guard-strategy.enum.js +1 -0
- package/dist/core/modules/auth/auth-guard-strategy.enum.js.map +1 -1
- package/dist/core/modules/auth/guards/auth.guard.js +11 -5
- package/dist/core/modules/auth/guards/auth.guard.js.map +1 -1
- package/dist/core/modules/auth/tokens.decorator.d.ts +1 -1
- package/dist/core/modules/better-auth/better-auth-auth.model.d.ts +9 -0
- package/dist/core/modules/better-auth/better-auth-auth.model.js +63 -0
- package/dist/core/modules/better-auth/better-auth-auth.model.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth-models.d.ts +43 -0
- package/dist/core/modules/better-auth/better-auth-models.js +181 -0
- package/dist/core/modules/better-auth/better-auth-models.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.d.ts +12 -0
- package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.js +70 -0
- package/dist/core/modules/better-auth/better-auth-rate-limit.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth-rate-limiter.service.d.ts +32 -0
- package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js +173 -0
- package/dist/core/modules/better-auth/better-auth-rate-limiter.service.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth-user.mapper.d.ts +43 -0
- package/dist/core/modules/better-auth/better-auth-user.mapper.js +159 -0
- package/dist/core/modules/better-auth/better-auth-user.mapper.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth.config.d.ts +9 -0
- package/dist/core/modules/better-auth/better-auth.config.js +254 -0
- package/dist/core/modules/better-auth/better-auth.config.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth.middleware.d.ts +20 -0
- package/dist/core/modules/better-auth/better-auth.middleware.js +79 -0
- package/dist/core/modules/better-auth/better-auth.middleware.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth.module.d.ts +38 -0
- package/dist/core/modules/better-auth/better-auth.module.js +253 -0
- package/dist/core/modules/better-auth/better-auth.module.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth.resolver.d.ts +45 -0
- package/dist/core/modules/better-auth/better-auth.resolver.js +221 -0
- package/dist/core/modules/better-auth/better-auth.resolver.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth.service.d.ts +37 -0
- package/dist/core/modules/better-auth/better-auth.service.js +148 -0
- package/dist/core/modules/better-auth/better-auth.service.js.map +1 -0
- package/dist/core/modules/better-auth/better-auth.types.d.ts +39 -0
- package/dist/core/modules/better-auth/better-auth.types.js +26 -0
- package/dist/core/modules/better-auth/better-auth.types.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.d.ts +66 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.js +491 -0
- package/dist/core/modules/better-auth/core-better-auth.controller.js.map +1 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.d.ts +59 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.js +538 -0
- package/dist/core/modules/better-auth/core-better-auth.resolver.js.map +1 -0
- package/dist/core/modules/better-auth/index.d.ts +13 -0
- package/dist/core/modules/better-auth/index.js +30 -0
- package/dist/core/modules/better-auth/index.js.map +1 -0
- package/dist/core/modules/user/core-user.model.d.ts +2 -0
- package/dist/core/modules/user/core-user.model.js +21 -0
- package/dist/core/modules/user/core-user.model.js.map +1 -1
- package/dist/core.module.js +7 -0
- package/dist/core.module.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/server/modules/better-auth/better-auth.controller.d.ts +10 -0
- package/dist/server/modules/better-auth/better-auth.controller.js +36 -0
- package/dist/server/modules/better-auth/better-auth.controller.js.map +1 -0
- package/dist/server/modules/better-auth/better-auth.module.d.ts +9 -0
- package/dist/server/modules/better-auth/better-auth.module.js +44 -0
- package/dist/server/modules/better-auth/better-auth.module.js.map +1 -0
- package/dist/server/modules/better-auth/better-auth.resolver.d.ts +45 -0
- package/dist/server/modules/better-auth/better-auth.resolver.js +221 -0
- package/dist/server/modules/better-auth/better-auth.resolver.js.map +1 -0
- package/dist/server/modules/file/file-info.model.d.ts +71 -3
- package/dist/server/modules/user/user.model.d.ts +169 -3
- package/dist/server/server.module.js +6 -1
- package/dist/server/server.module.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +21 -22
- package/src/config.env.ts +139 -1
- package/src/core/common/decorators/restricted.decorator.ts +2 -2
- package/src/core/common/helpers/filter.helper.ts +15 -17
- package/src/core/common/helpers/gridfs.helper.ts +5 -5
- package/src/core/common/helpers/input.helper.ts +2 -2
- package/src/core/common/interfaces/server-options.interface.ts +377 -20
- package/src/core/common/services/crud.service.ts +22 -22
- package/src/core/modules/auth/auth-guard-strategy.enum.ts +1 -0
- package/src/core/modules/auth/guards/auth.guard.ts +20 -6
- package/src/core/modules/better-auth/README.md +1422 -0
- package/src/core/modules/better-auth/better-auth-auth.model.ts +69 -0
- package/src/core/modules/better-auth/better-auth-models.ts +140 -0
- package/src/core/modules/better-auth/better-auth-rate-limit.middleware.ts +113 -0
- package/src/core/modules/better-auth/better-auth-rate-limiter.service.ts +326 -0
- package/src/core/modules/better-auth/better-auth-user.mapper.ts +269 -0
- package/src/core/modules/better-auth/better-auth.config.ts +488 -0
- package/src/core/modules/better-auth/better-auth.middleware.ts +111 -0
- package/src/core/modules/better-auth/better-auth.module.ts +474 -0
- package/src/core/modules/better-auth/better-auth.resolver.ts +213 -0
- package/src/core/modules/better-auth/better-auth.service.ts +314 -0
- package/src/core/modules/better-auth/better-auth.types.ts +90 -0
- package/src/core/modules/better-auth/core-better-auth.controller.ts +605 -0
- package/src/core/modules/better-auth/core-better-auth.resolver.ts +705 -0
- package/src/core/modules/better-auth/index.ts +32 -0
- package/src/core/modules/user/core-user.model.ts +29 -0
- package/src/core.module.ts +13 -0
- package/src/index.ts +6 -0
- package/src/server/modules/better-auth/better-auth.controller.ts +41 -0
- package/src/server/modules/better-auth/better-auth.module.ts +88 -0
- package/src/server/modules/better-auth/better-auth.resolver.ts +201 -0
- package/src/server/server.module.ts +10 -1
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { Inject, Injectable, Logger, Optional } from '@nestjs/common';
|
|
2
|
+
import { Request } from 'express';
|
|
3
|
+
|
|
4
|
+
import { IBetterAuth } from '../../common/interfaces/server-options.interface';
|
|
5
|
+
import { ConfigService } from '../../common/services/config.service';
|
|
6
|
+
import { BetterAuthSessionUser } from './better-auth-user.mapper';
|
|
7
|
+
import { BetterAuthInstance } from './better-auth.config';
|
|
8
|
+
import { BETTER_AUTH_INSTANCE } from './better-auth.module';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Result of a session validation
|
|
12
|
+
*/
|
|
13
|
+
export interface SessionResult {
|
|
14
|
+
session: null | {
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
expiresAt: Date;
|
|
17
|
+
id: string;
|
|
18
|
+
userId: string;
|
|
19
|
+
};
|
|
20
|
+
user: BetterAuthSessionUser | null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* BetterAuthService provides a NestJS-friendly wrapper around the better-auth instance.
|
|
25
|
+
*
|
|
26
|
+
* This service:
|
|
27
|
+
* - Provides access to the better-auth API
|
|
28
|
+
* - Offers typed methods for common auth operations
|
|
29
|
+
* - Handles the case when better-auth is disabled gracefully
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* @Injectable()
|
|
34
|
+
* export class MyService {
|
|
35
|
+
* constructor(private readonly betterAuthService: BetterAuthService) {}
|
|
36
|
+
*
|
|
37
|
+
* async doSomething() {
|
|
38
|
+
* if (this.betterAuthService.isEnabled()) {
|
|
39
|
+
* const api = this.betterAuthService.getApi();
|
|
40
|
+
* // Use better-auth API
|
|
41
|
+
* }
|
|
42
|
+
* }
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
@Injectable()
|
|
47
|
+
export class BetterAuthService {
|
|
48
|
+
private readonly logger = new Logger(BetterAuthService.name);
|
|
49
|
+
private readonly config: IBetterAuth;
|
|
50
|
+
|
|
51
|
+
constructor(
|
|
52
|
+
@Optional() @Inject(BETTER_AUTH_INSTANCE) private readonly authInstance: BetterAuthInstance | null,
|
|
53
|
+
@Optional() private readonly configService?: ConfigService,
|
|
54
|
+
) {
|
|
55
|
+
// Better-Auth is enabled by default (zero-config) - only disabled if explicitly set to false
|
|
56
|
+
this.config = this.configService?.get<IBetterAuth>('betterAuth') || {};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Checks if better-auth is enabled and initialized
|
|
61
|
+
* Returns true only if:
|
|
62
|
+
* 1. The better-auth instance was successfully created (not null/undefined)
|
|
63
|
+
* 2. Better-Auth was not explicitly disabled (enabled !== false)
|
|
64
|
+
*
|
|
65
|
+
* Better-Auth is enabled by default unless explicitly set to enabled: false
|
|
66
|
+
*/
|
|
67
|
+
isEnabled(): boolean {
|
|
68
|
+
// First check: authInstance must exist (not null or undefined)
|
|
69
|
+
if (!this.authInstance) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
// Second check: must not be explicitly disabled
|
|
73
|
+
return this.config?.enabled !== false;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Gets the better-auth instance
|
|
78
|
+
* Returns null if better-auth is disabled
|
|
79
|
+
*/
|
|
80
|
+
getInstance(): BetterAuthInstance | null {
|
|
81
|
+
return this.authInstance ?? null;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Gets the better-auth API for direct access to endpoints
|
|
86
|
+
* Returns null if better-auth is disabled
|
|
87
|
+
*/
|
|
88
|
+
getApi(): BetterAuthInstance['api'] | null {
|
|
89
|
+
return this.authInstance?.api || null;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Gets the current better-auth configuration
|
|
94
|
+
*/
|
|
95
|
+
getConfig(): IBetterAuth {
|
|
96
|
+
return this.config;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Checks if JWT plugin is enabled.
|
|
101
|
+
* JWT is enabled by default when the jwt config block is present,
|
|
102
|
+
* unless explicitly disabled with enabled: false.
|
|
103
|
+
*/
|
|
104
|
+
isJwtEnabled(): boolean {
|
|
105
|
+
return this.isEnabled() && !!this.config.jwt && this.config.jwt.enabled !== false;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Checks if 2FA is enabled.
|
|
110
|
+
* 2FA is enabled by default when the twoFactor config block is present,
|
|
111
|
+
* unless explicitly disabled with enabled: false.
|
|
112
|
+
*/
|
|
113
|
+
isTwoFactorEnabled(): boolean {
|
|
114
|
+
return this.isEnabled() && !!this.config.twoFactor && this.config.twoFactor.enabled !== false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Checks if Passkey/WebAuthn is enabled.
|
|
119
|
+
* Passkey is enabled by default when the passkey config block is present,
|
|
120
|
+
* unless explicitly disabled with enabled: false.
|
|
121
|
+
*/
|
|
122
|
+
isPasskeyEnabled(): boolean {
|
|
123
|
+
return this.isEnabled() && !!this.config.passkey && this.config.passkey.enabled !== false;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Gets the list of enabled social providers
|
|
128
|
+
* Dynamically iterates over all configured providers.
|
|
129
|
+
*
|
|
130
|
+
* A provider is considered enabled if:
|
|
131
|
+
* - It has clientId and clientSecret configured
|
|
132
|
+
* - It is NOT explicitly disabled (enabled !== false)
|
|
133
|
+
*
|
|
134
|
+
* This follows the same "enabled by default" pattern as Better-Auth itself.
|
|
135
|
+
*/
|
|
136
|
+
getEnabledSocialProviders(): string[] {
|
|
137
|
+
if (!this.isEnabled()) {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const providers: string[] = [];
|
|
142
|
+
|
|
143
|
+
// Dynamically iterate over all configured social providers
|
|
144
|
+
if (this.config.socialProviders) {
|
|
145
|
+
for (const [name, provider] of Object.entries(this.config.socialProviders)) {
|
|
146
|
+
// Provider is enabled if: has credentials AND not explicitly disabled
|
|
147
|
+
if (provider?.clientId && provider?.clientSecret && provider?.enabled !== false) {
|
|
148
|
+
providers.push(name);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return providers;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Gets the base path for better-auth endpoints
|
|
158
|
+
*/
|
|
159
|
+
getBasePath(): string {
|
|
160
|
+
return this.config.basePath || '/iam';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Gets the base URL for better-auth
|
|
165
|
+
*/
|
|
166
|
+
getBaseUrl(): string {
|
|
167
|
+
return this.config.baseUrl || 'http://localhost:3000';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// ===================================================================================================================
|
|
171
|
+
// Session Management Methods
|
|
172
|
+
// ===================================================================================================================
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Gets the current session from request headers
|
|
176
|
+
*
|
|
177
|
+
* @param req - Express request object or headers object
|
|
178
|
+
* @returns Session and user data, or null values if no valid session
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ```typescript
|
|
182
|
+
* const { session, user } = await betterAuthService.getSession(req);
|
|
183
|
+
* if (session) {
|
|
184
|
+
* console.log('User:', user.email);
|
|
185
|
+
* console.log('Session expires:', session.expiresAt);
|
|
186
|
+
* }
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
async getSession(req: Request | { headers: Record<string, string | string[] | undefined> }): Promise<SessionResult> {
|
|
190
|
+
if (!this.isEnabled()) {
|
|
191
|
+
return { session: null, user: null };
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const api = this.getApi();
|
|
195
|
+
if (!api) {
|
|
196
|
+
return { session: null, user: null };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
// Convert headers to the format Better-Auth expects
|
|
201
|
+
const headers = new Headers();
|
|
202
|
+
const reqHeaders = 'headers' in req ? req.headers : {};
|
|
203
|
+
|
|
204
|
+
for (const [key, value] of Object.entries(reqHeaders)) {
|
|
205
|
+
if (typeof value === 'string') {
|
|
206
|
+
headers.set(key, value);
|
|
207
|
+
} else if (Array.isArray(value)) {
|
|
208
|
+
headers.set(key, value.join(', '));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
const response = await api.getSession({ headers });
|
|
213
|
+
|
|
214
|
+
if (response && typeof response === 'object' && 'user' in response) {
|
|
215
|
+
return response as SessionResult;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return { session: null, user: null };
|
|
219
|
+
} catch (error) {
|
|
220
|
+
this.logger.debug(`getSession error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
221
|
+
return { session: null, user: null };
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Revokes a specific session (logout for that session)
|
|
227
|
+
*
|
|
228
|
+
* This should be called when a user wants to log out from a specific device/session.
|
|
229
|
+
* The session token is typically stored in a cookie or sent as a bearer token.
|
|
230
|
+
*
|
|
231
|
+
* @param sessionToken - The session token to revoke
|
|
232
|
+
* @returns true if session was revoked, false otherwise
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```typescript
|
|
236
|
+
* // Get session token from cookie or header
|
|
237
|
+
* const sessionToken = req.cookies['better-auth.session_token'];
|
|
238
|
+
* const success = await betterAuthService.revokeSession(sessionToken);
|
|
239
|
+
* if (success) {
|
|
240
|
+
* res.clearCookie('better-auth.session_token');
|
|
241
|
+
* }
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
async revokeSession(sessionToken: string): Promise<boolean> {
|
|
245
|
+
if (!this.isEnabled() || !sessionToken) {
|
|
246
|
+
return false;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const api = this.getApi();
|
|
250
|
+
if (!api) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
// Create headers with the session token
|
|
256
|
+
const headers = new Headers();
|
|
257
|
+
headers.set('Authorization', `Bearer ${sessionToken}`);
|
|
258
|
+
|
|
259
|
+
// Call Better-Auth's signOut endpoint
|
|
260
|
+
await api.signOut({ headers });
|
|
261
|
+
|
|
262
|
+
this.logger.debug('Session revoked successfully');
|
|
263
|
+
return true;
|
|
264
|
+
} catch (error) {
|
|
265
|
+
this.logger.debug(`revokeSession error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
266
|
+
return false;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Checks if a session is close to expiring
|
|
272
|
+
*
|
|
273
|
+
* @param session - The session object from getSession()
|
|
274
|
+
* @param thresholdMinutes - Minutes before expiry to consider "close to expiring" (default: 5)
|
|
275
|
+
* @returns true if session expires within the threshold
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```typescript
|
|
279
|
+
* const { session } = await betterAuthService.getSession(req);
|
|
280
|
+
* if (session && betterAuthService.isSessionExpiringSoon(session)) {
|
|
281
|
+
* // Prompt user to refresh their session
|
|
282
|
+
* }
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
285
|
+
isSessionExpiringSoon(session: SessionResult['session'], thresholdMinutes: number = 5): boolean {
|
|
286
|
+
if (!session?.expiresAt) {
|
|
287
|
+
return true; // No session or no expiry = treat as expiring
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
const expiresAt = new Date(session.expiresAt);
|
|
291
|
+
const now = new Date();
|
|
292
|
+
const thresholdMs = thresholdMinutes * 60 * 1000;
|
|
293
|
+
|
|
294
|
+
return expiresAt.getTime() - now.getTime() < thresholdMs;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Gets the remaining session time in seconds
|
|
299
|
+
*
|
|
300
|
+
* @param session - The session object from getSession()
|
|
301
|
+
* @returns Seconds until session expires, or 0 if expired/invalid
|
|
302
|
+
*/
|
|
303
|
+
getSessionTimeRemaining(session: SessionResult['session']): number {
|
|
304
|
+
if (!session?.expiresAt) {
|
|
305
|
+
return 0;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const expiresAt = new Date(session.expiresAt);
|
|
309
|
+
const now = new Date();
|
|
310
|
+
const remaining = Math.max(0, Math.floor((expiresAt.getTime() - now.getTime()) / 1000));
|
|
311
|
+
|
|
312
|
+
return remaining;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for Better-Auth API responses
|
|
3
|
+
*
|
|
4
|
+
* These types provide type safety for interactions with the Better-Auth API
|
|
5
|
+
* and reduce the need for `as any` casts throughout the codebase.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { BetterAuthSessionUser } from './better-auth-user.mapper';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Better-Auth 2FA verification response
|
|
12
|
+
*/
|
|
13
|
+
export interface BetterAuth2FAResponse {
|
|
14
|
+
session?: BetterAuthSessionResponse['session'];
|
|
15
|
+
token?: string;
|
|
16
|
+
user?: BetterAuthSessionUser;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Better-Auth session response from getSession API
|
|
21
|
+
*/
|
|
22
|
+
export interface BetterAuthSessionResponse {
|
|
23
|
+
session: {
|
|
24
|
+
createdAt: Date;
|
|
25
|
+
expiresAt: Date;
|
|
26
|
+
id: string;
|
|
27
|
+
token: string;
|
|
28
|
+
updatedAt: Date;
|
|
29
|
+
userId: string;
|
|
30
|
+
};
|
|
31
|
+
user: BetterAuthSessionUser;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Better-Auth sign-in response
|
|
36
|
+
*/
|
|
37
|
+
export interface BetterAuthSignInResponse {
|
|
38
|
+
session?: BetterAuthSessionResponse['session'];
|
|
39
|
+
token?: string;
|
|
40
|
+
twoFactorRedirect?: boolean;
|
|
41
|
+
user?: BetterAuthSessionUser;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Better-Auth sign-up response
|
|
46
|
+
*/
|
|
47
|
+
export interface BetterAuthSignUpResponse {
|
|
48
|
+
session?: BetterAuthSessionResponse['session'];
|
|
49
|
+
user?: BetterAuthSessionUser;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Type guard to check if response has session
|
|
54
|
+
* Preserves the original type while asserting session is defined
|
|
55
|
+
*/
|
|
56
|
+
export function hasSession<T>(response: T): response is T & { session: { expiresAt: Date; id: string } } {
|
|
57
|
+
return (
|
|
58
|
+
response !== null &&
|
|
59
|
+
typeof response === 'object' &&
|
|
60
|
+
'session' in response &&
|
|
61
|
+
(response as { session?: unknown }).session !== null &&
|
|
62
|
+
(response as { session?: unknown }).session !== undefined
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Type guard to check if response has user
|
|
68
|
+
* Preserves the original type while asserting user is defined
|
|
69
|
+
*/
|
|
70
|
+
export function hasUser<T>(response: T): response is T & { user: BetterAuthSessionUser } {
|
|
71
|
+
return (
|
|
72
|
+
response !== null &&
|
|
73
|
+
typeof response === 'object' &&
|
|
74
|
+
'user' in response &&
|
|
75
|
+
(response as { user?: unknown }).user !== null &&
|
|
76
|
+
(response as { user?: unknown }).user !== undefined
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Type guard to check if response requires 2FA
|
|
82
|
+
*/
|
|
83
|
+
export function requires2FA<T>(response: T): response is T & { twoFactorRedirect: true } {
|
|
84
|
+
return (
|
|
85
|
+
response !== null &&
|
|
86
|
+
typeof response === 'object' &&
|
|
87
|
+
'twoFactorRedirect' in response &&
|
|
88
|
+
(response as { twoFactorRedirect?: boolean }).twoFactorRedirect === true
|
|
89
|
+
);
|
|
90
|
+
}
|