@vunexa/lixa 0.0.1-alpha.20 → 0.0.1-alpha.21

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.
@@ -1,11 +1,245 @@
1
+ /**
2
+ * OAuth state data structure.
3
+ *
4
+ * @remarks
5
+ * This structure is used internally by Lixa to store OAuth flow state
6
+ * during the authorization process. It contains the information needed
7
+ * to complete the PKCE flow and route callbacks to the correct provider.
8
+ *
9
+ * @public
10
+ */
11
+ export interface StateData {
12
+ /**
13
+ * Provider name for callback routing.
14
+ * Used to identify which provider configuration to use when handling the callback.
15
+ *
16
+ * @example 'google', 'github', 'custom'
17
+ */
18
+ provider: string;
19
+ /**
20
+ * PKCE code verifier for secure token exchange.
21
+ * A cryptographically random string (64 hex characters) used in the PKCE flow
22
+ * to prevent authorization code interception attacks.
23
+ *
24
+ * @see RFC 7636 - Proof Key for Code Exchange
25
+ */
26
+ codeVerifier: string;
27
+ /**
28
+ * Unix timestamp in milliseconds when the state was created.
29
+ * Used for debugging and validation purposes.
30
+ */
31
+ createdAt: number;
32
+ }
33
+ /**
34
+ * Data access object for OAuth state storage.
35
+ *
36
+ * @remarks
37
+ * State storage is used during the OAuth authorization flow to:
38
+ * - Prevent CSRF attacks by validating the state parameter
39
+ * - Store PKCE code verifiers for secure token exchange
40
+ * - Maintain OAuth flow context across HTTP requests
41
+ *
42
+ * State data must persist across HTTP requests and support TTL (time-to-live).
43
+ * The default implementation uses in-memory cache, which is not suitable for production
44
+ * environments with multiple server instances or server restarts.
45
+ *
46
+ * For production, implement this interface with a distributed cache like Redis,
47
+ * or a database with TTL support.
48
+ *
49
+ * @example
50
+ * Redis implementation:
51
+ * ```typescript
52
+ * class RedisStateDao implements StateDao {
53
+ * constructor(private redis: RedisClient) {}
54
+ *
55
+ * async saveState(state: string, data: any, expiresInSeconds: number): Promise<void> {
56
+ * await this.redis.setex(`oauth:state:${state}`, expiresInSeconds, JSON.stringify(data));
57
+ * }
58
+ *
59
+ * async getState(state: string): Promise<any | null> {
60
+ * const data = await this.redis.get(`oauth:state:${state}`);
61
+ * return data ? JSON.parse(data) : null;
62
+ * }
63
+ *
64
+ * async deleteState(state: string): Promise<void> {
65
+ * await this.redis.del(`oauth:state:${state}`);
66
+ * }
67
+ * }
68
+ * ```
69
+ *
70
+ * @public
71
+ */
1
72
  export interface StateDao {
2
- saveState(state: string, data: any, expiresInSeconds: number): Promise<void>;
3
- getState(state: string): Promise<any | null>;
73
+ /**
74
+ * Saves OAuth state with expiration.
75
+ *
76
+ * @param state - The state parameter value (random string for CSRF protection)
77
+ * @param data - State data including provider name and PKCE code verifier
78
+ * @param expiresInSeconds - TTL in seconds (typically 300 for 5 minutes)
79
+ *
80
+ * @remarks
81
+ * The data object MUST include the following required fields:
82
+ * - **provider** (string): Provider name for callback routing (e.g., 'google', 'github')
83
+ * - **codeVerifier** (string): PKCE code verifier for secure token exchange (64 hex characters)
84
+ * - **createdAt** (number): Unix timestamp in milliseconds for debugging and validation
85
+ *
86
+ * These fields are automatically populated by Lixa during the authorization flow.
87
+ * The state is stored when generating the authorization URL and retrieved during
88
+ * the OAuth callback to complete the PKCE flow.
89
+ *
90
+ * @see {@link StateData} for the complete state data structure
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * await stateDao.saveState('random-state-123', {
95
+ * provider: 'google',
96
+ * codeVerifier: 'abc123...',
97
+ * createdAt: Date.now()
98
+ * }, 300);
99
+ * ```
100
+ */
101
+ saveState(state: string, data: StateData, expiresInSeconds: number): Promise<void>;
102
+ /**
103
+ * Retrieves OAuth state data.
104
+ *
105
+ * @param state - The state parameter value
106
+ * @returns State data or null if not found or expired
107
+ *
108
+ * @remarks
109
+ * This method is called during the OAuth callback to validate the state
110
+ * parameter and retrieve the PKCE code verifier for token exchange.
111
+ *
112
+ * The returned data will include:
113
+ * - provider: Provider name for routing
114
+ * - codeVerifier: PKCE code verifier for token exchange
115
+ * - createdAt: Timestamp when state was created
116
+ *
117
+ * @see {@link StateData} for the complete state data structure
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * const stateData = await stateDao.getState('random-state-123');
122
+ * if (!stateData) {
123
+ * throw new Error('Invalid or expired state');
124
+ * }
125
+ * console.log(stateData.provider); // 'google'
126
+ * console.log(stateData.codeVerifier); // 'abc123...'
127
+ * ```
128
+ */
129
+ getState(state: string): Promise<StateData | null>;
130
+ /**
131
+ * Deletes OAuth state (called after successful validation).
132
+ *
133
+ * @param state - The state parameter value
134
+ *
135
+ * @remarks
136
+ * This method should be called after successfully validating the state
137
+ * to prevent replay attacks. State should only be usable once.
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * await stateDao.deleteState('random-state-123');
142
+ * ```
143
+ */
4
144
  deleteState(state: string): Promise<void>;
5
145
  }
146
+ /**
147
+ * Data access object for session storage.
148
+ *
149
+ * @remarks
150
+ * Session storage is used to persist user sessions after successful OAuth authentication.
151
+ * Sessions must persist across HTTP requests and support TTL (time-to-live).
152
+ *
153
+ * The default implementation uses in-memory cache, which is not suitable for production
154
+ * environments with multiple server instances or server restarts.
155
+ *
156
+ * For production, implement this interface with a distributed cache like Redis,
157
+ * a database, or a session store like express-session.
158
+ *
159
+ * @example
160
+ * Database implementation:
161
+ * ```typescript
162
+ * class DatabaseSessionDao implements SessionDao {
163
+ * constructor(private db: Database) {}
164
+ *
165
+ * async saveSession(sessionId: string, session: Session, expiresInSeconds: number): Promise<void> {
166
+ * const expiresAt = new Date(Date.now() + expiresInSeconds * 1000);
167
+ * await this.db.sessions.create({
168
+ * id: sessionId,
169
+ * token: session.token,
170
+ * data: session.raw,
171
+ * expiresAt
172
+ * });
173
+ * }
174
+ *
175
+ * async getSession(sessionId: string): Promise<Session | null> {
176
+ * const record = await this.db.sessions.findOne({
177
+ * id: sessionId,
178
+ * expiresAt: { $gt: new Date() }
179
+ * });
180
+ * return record ? { token: record.token, raw: record.data } : null;
181
+ * }
182
+ *
183
+ * async deleteSession(sessionId: string): Promise<void> {
184
+ * await this.db.sessions.delete({ id: sessionId });
185
+ * }
186
+ * }
187
+ * ```
188
+ *
189
+ * @public
190
+ */
6
191
  export interface SessionDao {
7
- saveSession(session: string, data: any, expiresInSeconds: number): Promise<void>;
8
- getSession(session: string): Promise<any | null>;
9
- deleteSession(session: string): Promise<void>;
192
+ /**
193
+ * Saves a session with expiration.
194
+ *
195
+ * @param sessionId - Unique session identifier
196
+ * @param data - Session data from SessionStrategy.createSession()
197
+ * @param expiresInSeconds - TTL in seconds (typically 86400 for 24 hours)
198
+ *
199
+ * @remarks
200
+ * The session data structure is defined by your SessionStrategy implementation.
201
+ * The default strategy returns \{ token: string, raw: any \}.
202
+ *
203
+ * @example
204
+ * ```typescript
205
+ * await sessionDao.saveSession('session-123', \{
206
+ * token: 'access-token',
207
+ * raw: \{ userId: '456', email: 'user\@example.com' \}
208
+ * \}, 86400);
209
+ * ```
210
+ */
211
+ saveSession(sessionId: string, data: any, expiresInSeconds: number): Promise<void>;
212
+ /**
213
+ * Retrieves a session by ID.
214
+ *
215
+ * @param sessionId - Unique session identifier
216
+ * @returns Session data or null if not found or expired
217
+ *
218
+ * @remarks
219
+ * This method is called to retrieve user session data for authenticated requests.
220
+ *
221
+ * @example
222
+ * ```typescript
223
+ * const session = await sessionDao.getSession('session-123');
224
+ * if (!session) {
225
+ * throw new Error('Session not found or expired');
226
+ * }
227
+ * ```
228
+ */
229
+ getSession(sessionId: string): Promise<any | null>;
230
+ /**
231
+ * Deletes a session (e.g., on logout).
232
+ *
233
+ * @param sessionId - Unique session identifier
234
+ *
235
+ * @remarks
236
+ * This method should be called when a user logs out to invalidate their session.
237
+ *
238
+ * @example
239
+ * ```typescript
240
+ * await sessionDao.deleteSession('session-123');
241
+ * ```
242
+ */
243
+ deleteSession(sessionId: string): Promise<void>;
10
244
  }
11
245
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/dao/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IAC7C,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjF,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IACjD,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/C"}
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,MAAM,WAAW,UAAU;IACzB;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEnF;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IAEnD;;;;;;;;;;;;OAYG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD"}