lambder 1.0.120 → 1.0.122

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 CHANGED
@@ -37,8 +37,8 @@ const lambder = new Lambder({
37
37
 
38
38
  // Enable session
39
39
  lambder.enableDdbSession({
40
- tableName: "website-session",
41
- tableRegion: "us-east-1",
40
+ tableName: "website-session", // DynamoDB Table Name
41
+ tableRegion: "us-east-1", // DynamoDB Table Region
42
42
  sessionSalt: "8p6Vt+4b1w3N8d/dcJ47QF3DRkp9koFg0G" // Change salt
43
43
  });
44
44
 
@@ -221,13 +221,22 @@ lambder.addModule(async (lambder: Lambder): Promise<void> => {
221
221
  You can enable session tracking by:
222
222
 
223
223
  ```typescript
224
- // Enable session
224
+ // Enable sessions using a dynamodb session table
225
225
  lambder.enableDdbSession({
226
- tableName: "website-session",
227
- tableRegion: "us-east-1",
226
+ tableName: "website-session", // DynamoDB Table Name
227
+ tableRegion: "us-east-1", // DynamoDB Table Region
228
228
  sessionSalt: "8p6Vt+4b1w3N8d/dcJ47QF3DRkp9koFg0G" // Change salt
229
229
  });
230
230
  ```
231
+ #### DynamoDB Session Table Structure:
232
+
233
+ Session system is enabled by storing data in a DynamoDB session table.
234
+
235
+ - Primary Key: "pk"
236
+ - Sort Key: "sk"
237
+ - TTL Key: "expiresAt" (optional)
238
+
239
+ #### Session Controller
231
240
 
232
241
  After you enable the session, you can access to the session controller:
233
242
 
@@ -235,26 +244,26 @@ After you enable the session, you can access to the session controller:
235
244
  // Create session controller:
236
245
  const sessionController = lambder.getSessionController(ctx);
237
246
 
238
- /*
247
+ // Type for sessionController
239
248
  sessionController: {
240
- async createSession(sessionKey, data, ttlInSeconds):
249
+ async createSession(sessionKey, data, ttlInSeconds): session
241
250
  // Starts a new session and persists the session data to DDB.
242
251
 
243
- async fetchSession():
252
+ async fetchSession(): session
244
253
  // Fetch and validate if there is an existing session
245
254
  // This is automatically done for addSessionRoute and addSessionApi
246
255
  // Throws if session not found
247
256
 
248
- async fetchSessionIfExists():
257
+ async fetchSessionIfExists(): session|null
249
258
  // Runs fetchSession and returns the session if found. Otherwise return null
250
259
 
251
- async updateSessionData(updatedData):
260
+ async updateSessionData(updatedData): updatedSession
252
261
  // Updates the active sessions data and persist it to ddb.
253
262
 
254
- async endSession(): Start a new session
263
+ async endSession():
255
264
  // End session and delete from DDB.
256
265
 
257
- async endSessionAll(): Start a new session
266
+ async endSessionAll():
258
267
  // Ends and deletes all registered sessions for this sessionKey across all devices
259
268
  }
260
269
  */
@@ -474,13 +483,8 @@ const loadPageData = async () => {
474
483
  console.error("Failed to fetch page data:", error);
475
484
  }
476
485
  };
477
-
478
486
  ```
479
487
 
480
- ## Advanced Configuration
481
-
482
- Lambder is designed to be flexible and extensible, allowing for customized behaviors through hooks and custom error handling mechanisms.
483
-
484
488
  ## Contributing
485
489
 
486
490
  Contributions are welcome! Especially for documentation. If you have an idea for an improvement or have found a bug, please open an issue or submit a pull request.
package/deploy.sh CHANGED
@@ -9,8 +9,9 @@ npm version patch --no-git-tag-version
9
9
  npm run build
10
10
  npm publish
11
11
 
12
- git add .
13
- git commit
14
- git push -u origin main
15
-
16
12
  echo "All operations completed successfully"
13
+
14
+
15
+ # git add .
16
+ # git commit -m ""
17
+ # git git push -u origin main
package/dist/Lambder.d.ts CHANGED
@@ -20,6 +20,7 @@ export type LambderRenderContext = {
20
20
  lambdaContext: Context;
21
21
  _otherInternal: {
22
22
  isApiCall: boolean;
23
+ sessionCookieHeader: null | Record<"Set-Cookie", string[]>;
23
24
  };
24
25
  };
25
26
  type LambderModuleFunction = (lambderInstance: Lambder) => void | Promise<void>;
package/dist/Lambder.js CHANGED
@@ -36,7 +36,7 @@ export const createContext = (event, lambdaContext, apiPath) => {
36
36
  get, post, cookie,
37
37
  apiName, apiPayload,
38
38
  headers, session, lambdaContext,
39
- _otherInternal: { isApiCall }
39
+ _otherInternal: { isApiCall, sessionCookieHeader: null }
40
40
  };
41
41
  };
42
42
  export default class Lambder {
@@ -194,6 +194,7 @@ export default class Lambder {
194
194
  return new LambderSessionController({
195
195
  lambderSessionManager: this.lambderSessionManager,
196
196
  sessionTokenCookieKey: this.sessionTokenCookieKey,
197
+ sessionCsrfCookieKey: this.sessionCsrfCookieKey,
197
198
  ctx,
198
199
  });
199
200
  }
@@ -247,27 +248,11 @@ export default class Lambder {
247
248
  response = hookResponse;
248
249
  }
249
250
  // Apply session cookie if needed.
250
- if ((ctx.session?.sessionToken ?? null) !== (ctx?.cookie?.[this.sessionTokenCookieKey] ?? null)) {
251
- // Add session cookies
252
- if (ctx.session?.sessionToken) {
253
- response.multiValueHeaders = {
254
- ...(response.multiValueHeaders || {}),
255
- "Set-Cookie": [
256
- `${this.sessionTokenCookieKey}=${ctx.session.sessionToken}; Expires=${new Date(ctx.session.expiresAt * 1000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
257
- `${this.sessionCsrfCookieKey}=${ctx.session.csrfToken}; Expires=${new Date(ctx.session.expiresAt * 1000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
258
- ],
259
- };
260
- }
261
- else {
262
- // Delete session cookies
263
- response.multiValueHeaders = {
264
- ...(response.multiValueHeaders || {}),
265
- "Set-Cookie": [
266
- `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
267
- `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
268
- ],
269
- };
270
- }
251
+ if ((ctx._otherInternal.sessionCookieHeader)) {
252
+ response.multiValueHeaders = {
253
+ ...(response.multiValueHeaders || {}),
254
+ ...(ctx._otherInternal.sessionCookieHeader || {}),
255
+ };
271
256
  }
272
257
  resolve(response);
273
258
  }
@@ -4,10 +4,12 @@ import type { LambderSessionContext } from "./LambderSessionManager.js";
4
4
  export default class LambderSessionController {
5
5
  lambderSessionManager: LambderSessionManager;
6
6
  sessionTokenCookieKey: string;
7
+ sessionCsrfCookieKey: string;
7
8
  ctx: LambderRenderContext;
8
- constructor({ lambderSessionManager, sessionTokenCookieKey, ctx, }: {
9
+ constructor({ lambderSessionManager, sessionTokenCookieKey, sessionCsrfCookieKey, ctx, }: {
9
10
  lambderSessionManager: LambderSessionManager;
10
11
  sessionTokenCookieKey: string;
12
+ sessionCsrfCookieKey: string;
11
13
  ctx: LambderRenderContext;
12
14
  });
13
15
  private areRequestSessionTokensValid;
@@ -1,11 +1,13 @@
1
1
  export default class LambderSessionController {
2
2
  lambderSessionManager;
3
3
  sessionTokenCookieKey;
4
+ sessionCsrfCookieKey;
4
5
  ctx;
5
- constructor({ lambderSessionManager, sessionTokenCookieKey, ctx, }) {
6
- this.ctx = ctx;
7
- this.sessionTokenCookieKey = sessionTokenCookieKey;
6
+ constructor({ lambderSessionManager, sessionTokenCookieKey, sessionCsrfCookieKey, ctx, }) {
8
7
  this.lambderSessionManager = lambderSessionManager;
8
+ this.sessionTokenCookieKey = sessionTokenCookieKey;
9
+ this.sessionCsrfCookieKey = sessionCsrfCookieKey;
10
+ this.ctx = ctx;
9
11
  }
10
12
  ;
11
13
  areRequestSessionTokensValid() {
@@ -22,7 +24,14 @@ export default class LambderSessionController {
22
24
  }
23
25
  ;
24
26
  async createSession(sessionKey, data, ttlInSeconds) {
25
- this.ctx.session = await this.lambderSessionManager.createSession(sessionKey, data, ttlInSeconds);
27
+ const session = await this.lambderSessionManager.createSession(sessionKey, data, ttlInSeconds);
28
+ this.ctx._otherInternal.sessionCookieHeader = {
29
+ "Set-Cookie": [
30
+ `${this.sessionTokenCookieKey}=${session.sessionToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
31
+ `${this.sessionCsrfCookieKey}=${session.csrfToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
32
+ ],
33
+ };
34
+ this.ctx.session = session;
26
35
  return this.ctx.session;
27
36
  }
28
37
  ;
@@ -74,6 +83,12 @@ export default class LambderSessionController {
74
83
  if (!this.ctx.session)
75
84
  throw new Error("Session not found.");
76
85
  await this.lambderSessionManager.deleteSession(this.ctx.session);
86
+ this.ctx._otherInternal.sessionCookieHeader = {
87
+ "Set-Cookie": [
88
+ `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
89
+ `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
90
+ ],
91
+ };
77
92
  this.ctx.session = null;
78
93
  }
79
94
  ;
@@ -81,6 +96,12 @@ export default class LambderSessionController {
81
96
  if (!this.ctx.session)
82
97
  throw new Error("Session not found.");
83
98
  await this.lambderSessionManager.deleteSessionAll(this.ctx.session);
99
+ this.ctx._otherInternal.sessionCookieHeader = {
100
+ "Set-Cookie": [
101
+ `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
102
+ `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
103
+ ],
104
+ };
84
105
  this.ctx.session = null;
85
106
  }
86
107
  ;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lambder",
3
- "version": "1.0.120",
3
+ "version": "1.0.122",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/Lambder.ts CHANGED
@@ -24,7 +24,10 @@ export type LambderRenderContext = {
24
24
  headers: APIGatewayProxyEventHeaders;
25
25
  session: LambderSessionContext|null;
26
26
  lambdaContext: Context;
27
- _otherInternal: { isApiCall: boolean };
27
+ _otherInternal: {
28
+ isApiCall: boolean,
29
+ sessionCookieHeader: null|Record<"Set-Cookie",string[]>
30
+ };
28
31
  };
29
32
 
30
33
  type LambderModuleFunction = (lambderInstance: Lambder) => void | Promise<void>;
@@ -76,7 +79,7 @@ export const createContext = (
76
79
  get, post, cookie,
77
80
  apiName, apiPayload,
78
81
  headers, session, lambdaContext,
79
- _otherInternal: { isApiCall }
82
+ _otherInternal: { isApiCall, sessionCookieHeader: null }
80
83
  };
81
84
  }
82
85
 
@@ -279,6 +282,7 @@ export default class Lambder {
279
282
  return new LambderSessionController({
280
283
  lambderSessionManager: this.lambderSessionManager,
281
284
  sessionTokenCookieKey: this.sessionTokenCookieKey,
285
+ sessionCsrfCookieKey: this.sessionCsrfCookieKey,
282
286
  ctx,
283
287
  });
284
288
  }
@@ -338,25 +342,10 @@ export default class Lambder {
338
342
  response = hookResponse;
339
343
  }
340
344
  // Apply session cookie if needed.
341
- if((ctx.session?.sessionToken ?? null) !== (ctx?.cookie?.[this.sessionTokenCookieKey] ?? null)){
342
- // Add session cookies
343
- if(ctx.session?.sessionToken){
344
- response.multiValueHeaders = {
345
- ...(response.multiValueHeaders || {}),
346
- "Set-Cookie": [
347
- `${this.sessionTokenCookieKey}=${ctx.session.sessionToken}; Expires=${new Date(ctx.session.expiresAt * 1000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
348
- `${this.sessionCsrfCookieKey}=${ctx.session.csrfToken}; Expires=${new Date(ctx.session.expiresAt * 1000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
349
- ],
350
- };
351
- }else{
352
- // Delete session cookies
353
- response.multiValueHeaders = {
354
- ...(response.multiValueHeaders || {}),
355
- "Set-Cookie": [
356
- `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
357
- `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
358
- ],
359
- };
345
+ if((ctx._otherInternal.sessionCookieHeader)){
346
+ response.multiValueHeaders = {
347
+ ...(response.multiValueHeaders || {}),
348
+ ...(ctx._otherInternal.sessionCookieHeader || {}),
360
349
  }
361
350
  }
362
351
  resolve(response);
@@ -5,22 +5,26 @@ import type { LambderSessionContext } from "./LambderSessionManager.js";
5
5
  export default class LambderSessionController {
6
6
  lambderSessionManager: LambderSessionManager;
7
7
  sessionTokenCookieKey: string;
8
+ sessionCsrfCookieKey: string;
8
9
  ctx: LambderRenderContext;
9
10
 
10
11
  constructor(
11
12
  {
12
13
  lambderSessionManager,
13
14
  sessionTokenCookieKey,
15
+ sessionCsrfCookieKey,
14
16
  ctx,
15
17
  }: {
16
18
  lambderSessionManager: LambderSessionManager,
17
19
  sessionTokenCookieKey: string,
20
+ sessionCsrfCookieKey: string,
18
21
  ctx: LambderRenderContext,
19
22
  }
20
23
  ){
21
- this.ctx = ctx;
22
- this.sessionTokenCookieKey = sessionTokenCookieKey;
23
24
  this.lambderSessionManager = lambderSessionManager;
25
+ this.sessionTokenCookieKey = sessionTokenCookieKey;
26
+ this.sessionCsrfCookieKey = sessionCsrfCookieKey;
27
+ this.ctx = ctx;
24
28
  };
25
29
 
26
30
  private areRequestSessionTokensValid(): boolean {
@@ -37,7 +41,14 @@ export default class LambderSessionController {
37
41
  };
38
42
 
39
43
  async createSession (sessionKey: string, data?: any, ttlInSeconds?: number): Promise<LambderSessionContext> {
40
- this.ctx.session = await this.lambderSessionManager.createSession(sessionKey, data, ttlInSeconds);
44
+ const session = await this.lambderSessionManager.createSession(sessionKey, data, ttlInSeconds);
45
+ this.ctx._otherInternal.sessionCookieHeader = {
46
+ "Set-Cookie": [
47
+ `${this.sessionTokenCookieKey}=${session.sessionToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
48
+ `${this.sessionCsrfCookieKey}=${session.csrfToken}; Expires=${new Date(session.expiresAt * 1000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
49
+ ],
50
+ };
51
+ this.ctx.session = session;
41
52
  return this.ctx.session;
42
53
  };
43
54
 
@@ -83,12 +94,24 @@ export default class LambderSessionController {
83
94
  async endSession (){
84
95
  if(!this.ctx.session) throw new Error("Session not found.");
85
96
  await this.lambderSessionManager.deleteSession(this.ctx.session);
97
+ this.ctx._otherInternal.sessionCookieHeader = {
98
+ "Set-Cookie": [
99
+ `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
100
+ `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
101
+ ],
102
+ };
86
103
  this.ctx.session = null
87
104
  };
88
105
 
89
106
  async endSessionAll (){
90
107
  if(!this.ctx.session) throw new Error("Session not found.");
91
108
  await this.lambderSessionManager.deleteSessionAll(this.ctx.session);
109
+ this.ctx._otherInternal.sessionCookieHeader = {
110
+ "Set-Cookie": [
111
+ `${this.sessionTokenCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; HttpOnly; SameSite=Lax; Secure`,
112
+ `${this.sessionCsrfCookieKey}=0; Expires=${new Date(Date.now() - 100000).toUTCString()}; Path=/; SameSite=Lax; Secure`,
113
+ ],
114
+ };
92
115
  this.ctx.session = null
93
116
  };
94
117
  };