@vunexa/lixa 0.0.1-alpha.21 → 0.0.1-alpha.22
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/README.md +135 -58
- package/dist/dao/session-cache.d.ts +2 -2
- package/dist/dao/session-cache.d.ts.map +1 -1
- package/dist/dao/state-cache.d.ts +3 -3
- package/dist/dao/state-cache.d.ts.map +1 -1
- package/dist/dao/types.d.ts +13 -6
- package/dist/dao/types.d.ts.map +1 -1
- package/dist/export-types/index.d.ts +82 -21
- package/dist/index.cjs +9 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +81 -21
- package/dist/index.js +9 -9
- package/dist/index.js.map +1 -1
- package/dist/lixa.d.ts +7 -7
- package/dist/lixa.d.ts.map +1 -1
- package/dist/models/session.d.ts +60 -7
- package/dist/models/session.d.ts.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,7 +18,8 @@ A flexible, provider-agnostic OAuth 2.0 and OpenID Connect (OIDC) client library
|
|
|
18
18
|
- Custom provider registration with extensible provider interface
|
|
19
19
|
- Extensible session management via pluggable strategies
|
|
20
20
|
- PKCE (Proof Key for Code Exchange) support
|
|
21
|
-
- TypeScript-first with
|
|
21
|
+
- TypeScript-first with full type safety (zero `any` types)
|
|
22
|
+
- OAuth 2.0 and OpenID Connect spec-compliant types
|
|
22
23
|
- 100% test coverage with comprehensive error handling
|
|
23
24
|
|
|
24
25
|
---
|
|
@@ -70,9 +71,10 @@ const lixa = new Lixa({
|
|
|
70
71
|
// Optional: custom session strategy
|
|
71
72
|
sessionStrategy: {
|
|
72
73
|
createSession: async (tokenData) => {
|
|
73
|
-
//
|
|
74
|
+
// tokenData is typed as OAuthTokenResponse with proper OAuth 2.0 fields
|
|
75
|
+
// { access_token, token_type, expires_in?, refresh_token?, scope?, id_token? }
|
|
74
76
|
return {
|
|
75
|
-
token:
|
|
77
|
+
token: tokenData.access_token,
|
|
76
78
|
raw: tokenData,
|
|
77
79
|
};
|
|
78
80
|
},
|
|
@@ -251,11 +253,11 @@ const lixa = new Lixa({
|
|
|
251
253
|
By default, Lixa uses an in-memory cache for state management. For production applications or serverless environments, you should implement a custom state storage:
|
|
252
254
|
|
|
253
255
|
```typescript
|
|
254
|
-
import { Lixa } from "@vunexa/lixa";
|
|
256
|
+
import { Lixa, StateDao, StateData } from "@vunexa/lixa";
|
|
255
257
|
|
|
256
|
-
// Example: DynamoDB state storage
|
|
257
|
-
const dynamoDbStateDao = {
|
|
258
|
-
saveState: async (state: string, data:
|
|
258
|
+
// Example: DynamoDB state storage with proper typing
|
|
259
|
+
const dynamoDbStateDao: StateDao = {
|
|
260
|
+
saveState: async (state: string, data: StateData, expiresInSeconds: number) => {
|
|
259
261
|
await dynamoDB.put({
|
|
260
262
|
TableName: "oauth-states",
|
|
261
263
|
Item: {
|
|
@@ -266,7 +268,7 @@ const dynamoDbStateDao = {
|
|
|
266
268
|
});
|
|
267
269
|
},
|
|
268
270
|
|
|
269
|
-
getState: async (state: string) => {
|
|
271
|
+
getState: async (state: string): Promise<StateData | null> => {
|
|
270
272
|
const result = await dynamoDB.get({
|
|
271
273
|
TableName: "oauth-states",
|
|
272
274
|
Key: { state },
|
|
@@ -278,7 +280,7 @@ const dynamoDbStateDao = {
|
|
|
278
280
|
return null; // Expired
|
|
279
281
|
}
|
|
280
282
|
|
|
281
|
-
return JSON.parse(result.Item.data);
|
|
283
|
+
return JSON.parse(result.Item.data) as StateData;
|
|
282
284
|
},
|
|
283
285
|
|
|
284
286
|
deleteState: async (state: string) => {
|
|
@@ -295,15 +297,22 @@ const lixa = new Lixa({
|
|
|
295
297
|
});
|
|
296
298
|
```
|
|
297
299
|
|
|
298
|
-
**Important**: The
|
|
300
|
+
**Important**: The `StateData` type includes required fields:
|
|
301
|
+
- `provider` (string): Provider name for callback routing
|
|
302
|
+
- `codeVerifier` (string): PKCE code verifier (64 hex characters)
|
|
303
|
+
- `createdAt` (number): Unix timestamp in milliseconds
|
|
304
|
+
|
|
305
|
+
Make sure your storage preserves all fields in the data object.
|
|
299
306
|
|
|
300
307
|
### Custom Session Storage (SessionDao)
|
|
301
308
|
|
|
302
|
-
Similar to state storage, you can implement custom session storage:
|
|
309
|
+
Similar to state storage, you can implement custom session storage with proper typing:
|
|
303
310
|
|
|
304
311
|
```typescript
|
|
305
|
-
|
|
306
|
-
|
|
312
|
+
import { Lixa, SessionDao, Session } from "@vunexa/lixa";
|
|
313
|
+
|
|
314
|
+
const customSessionDao: SessionDao = {
|
|
315
|
+
saveSession: async <T = unknown>(sessionId: string, session: T, expiresInSeconds: number) => {
|
|
307
316
|
// Store session in your database
|
|
308
317
|
await db.sessions.create({
|
|
309
318
|
id: sessionId,
|
|
@@ -312,12 +321,12 @@ const customSessionDao = {
|
|
|
312
321
|
});
|
|
313
322
|
},
|
|
314
323
|
|
|
315
|
-
getSession: async (sessionId: string) => {
|
|
324
|
+
getSession: async <T = unknown>(sessionId: string): Promise<T | null> => {
|
|
316
325
|
const session = await db.sessions.findById(sessionId);
|
|
317
326
|
if (!session || session.expiresAt < Date.now()) {
|
|
318
327
|
return null;
|
|
319
328
|
}
|
|
320
|
-
return session.data;
|
|
329
|
+
return session.data as T;
|
|
321
330
|
},
|
|
322
331
|
|
|
323
332
|
deleteSession: async (sessionId: string) => {
|
|
@@ -333,12 +342,29 @@ const lixa = new Lixa({
|
|
|
333
342
|
|
|
334
343
|
### Custom Session Strategy
|
|
335
344
|
|
|
336
|
-
The session strategy controls how user sessions are created from OAuth tokens:
|
|
345
|
+
The session strategy controls how user sessions are created from OAuth tokens. The `tokenData` parameter is typed as `OAuthTokenResponse` with proper OAuth 2.0 fields:
|
|
337
346
|
|
|
338
347
|
```typescript
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
348
|
+
import { Lixa, SessionStrategy, OAuthTokenResponse, Session } from "@vunexa/lixa";
|
|
349
|
+
|
|
350
|
+
// Define custom session data structure
|
|
351
|
+
interface CustomSessionData extends OAuthTokenResponse {
|
|
352
|
+
userId: string;
|
|
353
|
+
userInfo: {
|
|
354
|
+
email: string;
|
|
355
|
+
name: string;
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
const customSessionStrategy: SessionStrategy = {
|
|
360
|
+
createSession: async (tokenData: OAuthTokenResponse): Promise<Session<CustomSessionData>> => {
|
|
361
|
+
// tokenData is properly typed with OAuth 2.0 fields:
|
|
362
|
+
// - access_token: string (required)
|
|
363
|
+
// - token_type: string (required)
|
|
364
|
+
// - expires_in?: number
|
|
365
|
+
// - refresh_token?: string
|
|
366
|
+
// - scope?: string
|
|
367
|
+
// - id_token?: string (for OIDC providers)
|
|
342
368
|
|
|
343
369
|
// Decode ID token to get user info (for OIDC providers like Google)
|
|
344
370
|
let userInfo;
|
|
@@ -493,21 +519,30 @@ saveState: async (state: string, data: any, expiresInSeconds: number) => {
|
|
|
493
519
|
**Solution**: Decode the `id_token` (for OIDC providers) or fetch user info from the provider's API:
|
|
494
520
|
|
|
495
521
|
```typescript
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
522
|
+
import { SessionStrategy, OAuthTokenResponse } from "@vunexa/lixa";
|
|
523
|
+
|
|
524
|
+
const strategy: SessionStrategy = {
|
|
525
|
+
createSession: async (tokenData: OAuthTokenResponse) => {
|
|
526
|
+
// For OIDC providers (Google, etc.) - id_token is properly typed
|
|
527
|
+
if (tokenData.id_token) {
|
|
528
|
+
const base64Payload = tokenData.id_token.split('.')[1];
|
|
529
|
+
const userInfo = JSON.parse(Buffer.from(base64Payload, 'base64').toString());
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// For OAuth-only providers (GitHub, etc.) - access_token is guaranteed to exist
|
|
533
|
+
else {
|
|
534
|
+
const response = await fetch(providerUserInfoEndpoint, {
|
|
535
|
+
headers: { Authorization: `Bearer ${tokenData.access_token}` }
|
|
536
|
+
});
|
|
537
|
+
const userInfo = await response.json();
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
return {
|
|
541
|
+
token: tokenData.access_token,
|
|
542
|
+
raw: tokenData
|
|
543
|
+
};
|
|
509
544
|
}
|
|
510
|
-
}
|
|
545
|
+
};
|
|
511
546
|
```
|
|
512
547
|
|
|
513
548
|
## API Reference
|
|
@@ -533,14 +568,27 @@ createSession: async (tokenData) => {
|
|
|
533
568
|
|
|
534
569
|
### Types
|
|
535
570
|
|
|
571
|
+
All types are fully typed with zero `any` types, following OAuth 2.0 and OpenID Connect specifications:
|
|
572
|
+
|
|
536
573
|
```typescript
|
|
574
|
+
// OAuth 2.0 token response (RFC 6749 Section 5.1)
|
|
575
|
+
interface OAuthTokenResponse {
|
|
576
|
+
access_token: string; // Required: OAuth access token
|
|
577
|
+
token_type: string; // Required: Token type (usually "Bearer")
|
|
578
|
+
expires_in?: number; // Optional: Token expiration in seconds
|
|
579
|
+
refresh_token?: string; // Optional: Refresh token
|
|
580
|
+
scope?: string; // Optional: Granted scopes (space-separated)
|
|
581
|
+
id_token?: string; // Optional: OpenID Connect ID token (JWT)
|
|
582
|
+
[key: string]: unknown; // Additional provider-specific fields
|
|
583
|
+
}
|
|
584
|
+
|
|
537
585
|
// Provider configuration with inline provider support
|
|
538
586
|
type ProviderConfig = {
|
|
539
587
|
clientId: string;
|
|
540
588
|
clientSecret: string;
|
|
541
589
|
redirectUri: string;
|
|
542
590
|
scopes: string[];
|
|
543
|
-
extraConfig?: Record<string,
|
|
591
|
+
extraConfig?: Record<string, string>;
|
|
544
592
|
} & (
|
|
545
593
|
| { provider?: never } // Built-in provider (no provider field)
|
|
546
594
|
| { provider: IProvider } // Custom provider (provider field required)
|
|
@@ -555,12 +603,12 @@ interface LixaConfig<TProviders = Record<string, ProviderConfig>> {
|
|
|
555
603
|
}
|
|
556
604
|
|
|
557
605
|
interface SessionStrategy {
|
|
558
|
-
createSession(tokenData:
|
|
606
|
+
createSession(tokenData: OAuthTokenResponse): Promise<Session>;
|
|
559
607
|
}
|
|
560
608
|
|
|
561
|
-
interface Session {
|
|
609
|
+
interface Session<TRaw = OAuthTokenResponse> {
|
|
562
610
|
token: string;
|
|
563
|
-
raw:
|
|
611
|
+
raw: TRaw; // Defaults to OAuthTokenResponse, can be extended
|
|
564
612
|
}
|
|
565
613
|
|
|
566
614
|
interface StateData {
|
|
@@ -576,8 +624,8 @@ interface StateDao {
|
|
|
576
624
|
}
|
|
577
625
|
|
|
578
626
|
interface SessionDao {
|
|
579
|
-
saveSession(sessionId: string, session:
|
|
580
|
-
getSession(sessionId: string): Promise<
|
|
627
|
+
saveSession<T = unknown>(sessionId: string, session: T, expiresInSeconds: number): Promise<void>;
|
|
628
|
+
getSession<T = unknown>(sessionId: string): Promise<T | null>;
|
|
581
629
|
deleteSession(sessionId: string): Promise<void>;
|
|
582
630
|
}
|
|
583
631
|
|
|
@@ -642,16 +690,26 @@ import { GithubProvider } from "@vunexa/lixa-providers";
|
|
|
642
690
|
|
|
643
691
|
### SessionStrategy Interface
|
|
644
692
|
|
|
645
|
-
The `SessionStrategy` interface allows you to customize how OAuth tokens are converted into application sessions
|
|
693
|
+
The `SessionStrategy` interface allows you to customize how OAuth tokens are converted into application sessions. The `tokenData` parameter is fully typed as `OAuthTokenResponse`:
|
|
646
694
|
|
|
647
695
|
```typescript
|
|
648
696
|
interface SessionStrategy {
|
|
649
|
-
createSession(tokenData:
|
|
697
|
+
createSession(tokenData: OAuthTokenResponse): Promise<Session>;
|
|
650
698
|
}
|
|
651
699
|
|
|
652
|
-
interface Session {
|
|
700
|
+
interface Session<TRaw = OAuthTokenResponse> {
|
|
653
701
|
token: string; // Your session identifier
|
|
654
|
-
raw:
|
|
702
|
+
raw: TRaw; // Session data (defaults to OAuthTokenResponse)
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
interface OAuthTokenResponse {
|
|
706
|
+
access_token: string; // Required
|
|
707
|
+
token_type: string; // Required
|
|
708
|
+
expires_in?: number; // Optional
|
|
709
|
+
refresh_token?: string; // Optional
|
|
710
|
+
scope?: string; // Optional
|
|
711
|
+
id_token?: string; // Optional (OIDC)
|
|
712
|
+
[key: string]: unknown; // Provider-specific fields
|
|
655
713
|
}
|
|
656
714
|
```
|
|
657
715
|
|
|
@@ -662,17 +720,28 @@ interface Session {
|
|
|
662
720
|
- Store tokens securely
|
|
663
721
|
- Add custom claims or metadata
|
|
664
722
|
|
|
665
|
-
**Example with database integration:**
|
|
723
|
+
**Example with database integration and proper typing:**
|
|
666
724
|
```typescript
|
|
725
|
+
import { SessionStrategy, OAuthTokenResponse, Session } from "@vunexa/lixa";
|
|
726
|
+
|
|
727
|
+
interface CustomSessionData extends OAuthTokenResponse {
|
|
728
|
+
userId: string;
|
|
729
|
+
}
|
|
730
|
+
|
|
667
731
|
const dbSessionStrategy: SessionStrategy = {
|
|
668
|
-
createSession: async (tokenData) => {
|
|
732
|
+
createSession: async (tokenData: OAuthTokenResponse): Promise<Session<CustomSessionData>> => {
|
|
733
|
+
// tokenData is properly typed with OAuth 2.0 fields
|
|
734
|
+
// TypeScript will catch errors like tokenData.id_tokn (typo)
|
|
735
|
+
|
|
669
736
|
// Decode ID token (for OIDC providers)
|
|
670
|
-
const payload =
|
|
737
|
+
const payload = tokenData.id_token
|
|
738
|
+
? decodeJwt(tokenData.id_token)
|
|
739
|
+
: null;
|
|
671
740
|
|
|
672
741
|
// Create/update user
|
|
673
742
|
const user = await db.users.upsert({
|
|
674
|
-
email: payload
|
|
675
|
-
name: payload
|
|
743
|
+
email: payload?.email,
|
|
744
|
+
name: payload?.name
|
|
676
745
|
});
|
|
677
746
|
|
|
678
747
|
// Generate session
|
|
@@ -681,12 +750,18 @@ const dbSessionStrategy: SessionStrategy = {
|
|
|
681
750
|
id: sessionId,
|
|
682
751
|
userId: user.id,
|
|
683
752
|
accessToken: tokenData.access_token,
|
|
684
|
-
refreshToken: tokenData.refresh_token
|
|
753
|
+
refreshToken: tokenData.refresh_token,
|
|
754
|
+
expiresAt: tokenData.expires_in
|
|
755
|
+
? new Date(Date.now() + tokenData.expires_in * 1000)
|
|
756
|
+
: null
|
|
685
757
|
});
|
|
686
758
|
|
|
687
759
|
return {
|
|
688
760
|
token: sessionId,
|
|
689
|
-
raw: {
|
|
761
|
+
raw: {
|
|
762
|
+
...tokenData,
|
|
763
|
+
userId: user.id
|
|
764
|
+
}
|
|
690
765
|
};
|
|
691
766
|
}
|
|
692
767
|
};
|
|
@@ -739,20 +814,22 @@ const redisStateDao: StateDao = {
|
|
|
739
814
|
|
|
740
815
|
### SessionDao Interface
|
|
741
816
|
|
|
742
|
-
The `SessionDao` interface manages persistent user session storage:
|
|
817
|
+
The `SessionDao` interface manages persistent user session storage with generic typing for flexibility:
|
|
743
818
|
|
|
744
819
|
```typescript
|
|
745
820
|
interface SessionDao {
|
|
746
|
-
saveSession(sessionId: string, data:
|
|
747
|
-
getSession(sessionId: string): Promise<
|
|
821
|
+
saveSession<T = unknown>(sessionId: string, data: T, expiresInSeconds: number): Promise<void>;
|
|
822
|
+
getSession<T = unknown>(sessionId: string): Promise<T | null>;
|
|
748
823
|
deleteSession(sessionId: string): Promise<void>;
|
|
749
824
|
}
|
|
750
825
|
```
|
|
751
826
|
|
|
752
|
-
**Example with database:**
|
|
827
|
+
**Example with database and proper typing:**
|
|
753
828
|
```typescript
|
|
829
|
+
import { SessionDao, Session } from "@vunexa/lixa";
|
|
830
|
+
|
|
754
831
|
const dbSessionDao: SessionDao = {
|
|
755
|
-
saveSession: async (sessionId, data, expiresInSeconds) => {
|
|
832
|
+
saveSession: async <T = unknown>(sessionId: string, data: T, expiresInSeconds: number) => {
|
|
756
833
|
const expiresAt = new Date(Date.now() + expiresInSeconds * 1000);
|
|
757
834
|
await db.sessions.create({
|
|
758
835
|
id: sessionId,
|
|
@@ -761,15 +838,15 @@ const dbSessionDao: SessionDao = {
|
|
|
761
838
|
});
|
|
762
839
|
},
|
|
763
840
|
|
|
764
|
-
getSession: async (sessionId) => {
|
|
841
|
+
getSession: async <T = unknown>(sessionId: string): Promise<T | null> => {
|
|
765
842
|
const session = await db.sessions.findOne({
|
|
766
843
|
id: sessionId,
|
|
767
844
|
expiresAt: { $gt: new Date() }
|
|
768
845
|
});
|
|
769
|
-
return session ? JSON.parse(session.data) : null;
|
|
846
|
+
return session ? JSON.parse(session.data) as T : null;
|
|
770
847
|
},
|
|
771
848
|
|
|
772
|
-
deleteSession: async (sessionId) => {
|
|
849
|
+
deleteSession: async (sessionId: string) => {
|
|
773
850
|
await db.sessions.delete({ id: sessionId });
|
|
774
851
|
}
|
|
775
852
|
};
|
|
@@ -2,8 +2,8 @@ import { SessionDao } from "./types";
|
|
|
2
2
|
declare class LocalSessionCache implements SessionDao {
|
|
3
3
|
private cache;
|
|
4
4
|
constructor(defaultTtlSeconds?: number);
|
|
5
|
-
saveSession(state: string, data:
|
|
6
|
-
getSession(state: string): Promise<
|
|
5
|
+
saveSession<T = unknown>(state: string, data: T, expiresInSeconds: number): Promise<void>;
|
|
6
|
+
getSession<T = unknown>(state: string): Promise<T | null>;
|
|
7
7
|
deleteSession(state: string): Promise<void>;
|
|
8
8
|
}
|
|
9
9
|
export { LocalSessionCache };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-cache.d.ts","sourceRoot":"","sources":["../../src/dao/session-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,cAAM,iBAAkB,YAAW,UAAU;IAC3C,OAAO,CAAC,KAAK,CAAY;gBAEb,iBAAiB,GAAE,MAAY;IAIrC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"session-cache.d.ts","sourceRoot":"","sources":["../../src/dao/session-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,cAAM,iBAAkB,YAAW,UAAU;IAC3C,OAAO,CAAC,KAAK,CAAY;gBAEb,iBAAiB,GAAE,MAAY;IAIrC,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzF,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAIzD,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGlD;AAED,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { StateDao } from "./types";
|
|
1
|
+
import { StateDao, StateData } from "./types";
|
|
2
2
|
declare class LocalStateCache implements StateDao {
|
|
3
3
|
private cache;
|
|
4
4
|
constructor(defaultTtlSeconds?: number);
|
|
5
|
-
saveState(state: string, data:
|
|
6
|
-
getState(state: string): Promise<
|
|
5
|
+
saveState(state: string, data: StateData, expiresInSeconds: number): Promise<void>;
|
|
6
|
+
getState(state: string): Promise<StateData | null>;
|
|
7
7
|
deleteState(state: string): Promise<void>;
|
|
8
8
|
}
|
|
9
9
|
export { LocalStateCache };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"state-cache.d.ts","sourceRoot":"","sources":["../../src/dao/state-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"state-cache.d.ts","sourceRoot":"","sources":["../../src/dao/state-cache.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAE9C,cAAM,eAAgB,YAAW,QAAQ;IACvC,OAAO,CAAC,KAAK,CAAY;gBAEb,iBAAiB,GAAE,MAAY;IAIrC,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlF,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;IAIlD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGhD;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
|
package/dist/dao/types.d.ts
CHANGED
|
@@ -52,11 +52,11 @@ export interface StateData {
|
|
|
52
52
|
* class RedisStateDao implements StateDao {
|
|
53
53
|
* constructor(private redis: RedisClient) {}
|
|
54
54
|
*
|
|
55
|
-
* async saveState(state: string, data:
|
|
55
|
+
* async saveState(state: string, data: StateData, expiresInSeconds: number): Promise<void> {
|
|
56
56
|
* await this.redis.setex(`oauth:state:${state}`, expiresInSeconds, JSON.stringify(data));
|
|
57
57
|
* }
|
|
58
58
|
*
|
|
59
|
-
* async getState(state: string): Promise<
|
|
59
|
+
* async getState(state: string): Promise<StateData | null> {
|
|
60
60
|
* const data = await this.redis.get(`oauth:state:${state}`);
|
|
61
61
|
* return data ? JSON.parse(data) : null;
|
|
62
62
|
* }
|
|
@@ -159,6 +159,8 @@ export interface StateDao {
|
|
|
159
159
|
* @example
|
|
160
160
|
* Database implementation:
|
|
161
161
|
* ```typescript
|
|
162
|
+
* import { Session } from '../models/session';
|
|
163
|
+
*
|
|
162
164
|
* class DatabaseSessionDao implements SessionDao {
|
|
163
165
|
* constructor(private db: Database) {}
|
|
164
166
|
*
|
|
@@ -198,17 +200,21 @@ export interface SessionDao {
|
|
|
198
200
|
*
|
|
199
201
|
* @remarks
|
|
200
202
|
* The session data structure is defined by your SessionStrategy implementation.
|
|
201
|
-
* The default strategy returns
|
|
203
|
+
* The default strategy returns a Session object with token and raw OAuth token response.
|
|
202
204
|
*
|
|
203
205
|
* @example
|
|
204
206
|
* ```typescript
|
|
205
207
|
* await sessionDao.saveSession('session-123', \{
|
|
206
208
|
* token: 'access-token',
|
|
207
|
-
* raw: \{
|
|
209
|
+
* raw: \{
|
|
210
|
+
* access_token: 'token',
|
|
211
|
+
* token_type: 'Bearer',
|
|
212
|
+
* expires_in: 3600
|
|
213
|
+
* \}
|
|
208
214
|
* \}, 86400);
|
|
209
215
|
* ```
|
|
210
216
|
*/
|
|
211
|
-
saveSession(sessionId: string, data:
|
|
217
|
+
saveSession<T = unknown>(sessionId: string, data: T, expiresInSeconds: number): Promise<void>;
|
|
212
218
|
/**
|
|
213
219
|
* Retrieves a session by ID.
|
|
214
220
|
*
|
|
@@ -217,6 +223,7 @@ export interface SessionDao {
|
|
|
217
223
|
*
|
|
218
224
|
* @remarks
|
|
219
225
|
* This method is called to retrieve user session data for authenticated requests.
|
|
226
|
+
* The returned data should match the structure saved by saveSession.
|
|
220
227
|
*
|
|
221
228
|
* @example
|
|
222
229
|
* ```typescript
|
|
@@ -226,7 +233,7 @@ export interface SessionDao {
|
|
|
226
233
|
* }
|
|
227
234
|
* ```
|
|
228
235
|
*/
|
|
229
|
-
getSession(sessionId: string): Promise<
|
|
236
|
+
getSession<T = unknown>(sessionId: string): Promise<T | null>;
|
|
230
237
|
/**
|
|
231
238
|
* Deletes a session (e.g., on logout).
|
|
232
239
|
*
|
package/dist/dao/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dao/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnF;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAEnD;;;;;;;;;;;;;OAaG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dao/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnF;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAEnD;;;;;;;;;;;;;OAaG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9F;;;;;;;;;;;;;;;;;OAiBG;IACH,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAE9D;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD"}
|