@adonisjs/session 7.0.0-1 → 7.0.0-3

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 (45) hide show
  1. package/README.md +5 -8
  2. package/build/index.d.ts +5 -3
  3. package/build/index.js +5 -3
  4. package/build/providers/session_provider.d.ts +6 -8
  5. package/build/providers/session_provider.js +14 -24
  6. package/build/src/client.d.ts +13 -25
  7. package/build/src/client.js +24 -43
  8. package/build/src/debug.d.ts +3 -0
  9. package/build/src/debug.js +10 -0
  10. package/build/src/define_config.d.ts +6 -3
  11. package/build/src/define_config.js +34 -5
  12. package/build/src/drivers/cookie.d.ts +7 -9
  13. package/build/src/drivers/cookie.js +10 -6
  14. package/build/src/drivers/file.d.ts +11 -14
  15. package/build/src/drivers/file.js +89 -33
  16. package/build/src/drivers/memory.d.ts +4 -8
  17. package/build/src/drivers/memory.js +0 -3
  18. package/build/src/drivers/redis.d.ts +4 -6
  19. package/build/src/drivers/redis.js +24 -28
  20. package/build/src/drivers_collection.d.ts +22 -0
  21. package/build/src/drivers_collection.js +38 -0
  22. package/build/src/errors.d.ts +8 -0
  23. package/build/src/errors.js +17 -0
  24. package/build/src/helpers.d.ts +6 -0
  25. package/build/src/helpers.js +37 -0
  26. package/build/src/session.d.ts +86 -59
  27. package/build/src/session.js +221 -221
  28. package/build/src/session_middleware.d.ts +19 -2
  29. package/build/src/session_middleware.js +43 -4
  30. package/build/src/store.d.ts +17 -14
  31. package/build/src/store.js +33 -17
  32. package/build/src/types/extended.d.ts +19 -0
  33. package/build/src/types/main.d.ts +106 -0
  34. package/build/src/types/main.js +9 -0
  35. package/package.json +26 -22
  36. package/build/src/bindings/api_client.d.ts +0 -2
  37. package/build/src/bindings/api_client.js +0 -135
  38. package/build/src/bindings/http_context.d.ts +0 -5
  39. package/build/src/bindings/http_context.js +0 -17
  40. package/build/src/bindings/types.d.ts +0 -77
  41. package/build/src/session_manager.d.ts +0 -38
  42. package/build/src/session_manager.js +0 -149
  43. package/build/src/types.d.ts +0 -61
  44. package/build/src/types.js +0 -1
  45. /package/build/src/{bindings/types.js → types/extended.js} +0 -0
package/README.md CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  <br />
4
4
 
5
- [![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url] [![snyk-image]][snyk-url]
5
+ [![gh-workflow-image]][gh-workflow-url] [![npm-image]][npm-url] ![][typescript-image] [![license-image]][license-url]
6
6
 
7
7
  ## Introduction
8
- Add sessions to your AdonisJS application. Cookie, Redis, and File drivers are included out of the box.
8
+ Use sessions in your AdonisJS applications with a unified API to persist session data across different data-stores. Has inbuilt support for **cookie**, **files**, and **redis** drivers.
9
9
 
10
10
  ## Official Documentation
11
11
  The documentation is available on the [AdonisJS website](https://docs.adonisjs.com/guides/sessions)
@@ -19,10 +19,10 @@ We encourage you to read the [contribution guide](https://github.com/adonisjs/.g
19
19
  In order to ensure that the AdonisJS community is welcoming to all, please review and abide by the [Code of Conduct](https://github.com/adonisjs/.github/blob/main/docs/CODE_OF_CONDUCT.md).
20
20
 
21
21
  ## License
22
- AdonisJS ally is open-sourced software licensed under the [MIT license](LICENSE.md).
22
+ AdonisJS session is open-sourced software licensed under the [MIT license](LICENSE.md).
23
23
 
24
- [gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/session/test.yml?style=for-the-badge
25
- [gh-workflow-url]: https://github.com/adonisjs/session/actions/workflows/test.yml "Github action"
24
+ [gh-workflow-image]: https://img.shields.io/github/actions/workflow/status/adonisjs/session/checks.yml?style=for-the-badge
25
+ [gh-workflow-url]: https://github.com/adonisjs/session/actions/workflows/checks.yml "Github action"
26
26
 
27
27
  [npm-image]: https://img.shields.io/npm/v/@adonisjs/session/latest.svg?style=for-the-badge&logo=npm
28
28
  [npm-url]: https://www.npmjs.com/package/@adonisjs/session/v/latest "npm"
@@ -31,6 +31,3 @@ AdonisJS ally is open-sourced software licensed under the [MIT license](LICENSE.
31
31
 
32
32
  [license-url]: LICENSE.md
33
33
  [license-image]: https://img.shields.io/github/license/adonisjs/session?style=for-the-badge
34
-
35
- [snyk-image]: https://img.shields.io/snyk/vulnerabilities/github/adonisjs/session?label=Snyk%20Vulnerabilities&style=for-the-badge
36
- [snyk-url]: https://snyk.io/test/github/adonisjs/session?targetFile=package.json "snyk"
package/build/index.d.ts CHANGED
@@ -6,7 +6,9 @@
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
8
8
  */
9
- import './src/bindings/types.js';
10
- export { defineConfig } from './src/define_config.js';
11
- export { stubsRoot } from './stubs/main.js';
9
+ import './src/types/extended.js';
10
+ export * as errors from './src/errors.js';
12
11
  export { configure } from './configure.js';
12
+ export { stubsRoot } from './stubs/main.js';
13
+ export { defineConfig } from './src/define_config.js';
14
+ export { default as driversList } from './src/drivers_collection.js';
package/build/index.js CHANGED
@@ -6,7 +6,9 @@
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
8
8
  */
9
- import './src/bindings/types.js';
10
- export { defineConfig } from './src/define_config.js';
11
- export { stubsRoot } from './stubs/main.js';
9
+ import './src/types/extended.js';
10
+ export * as errors from './src/errors.js';
12
11
  export { configure } from './configure.js';
12
+ export { stubsRoot } from './stubs/main.js';
13
+ export { defineConfig } from './src/define_config.js';
14
+ export { default as driversList } from './src/drivers_collection.js';
@@ -1,13 +1,11 @@
1
- import { ApplicationService } from '@adonisjs/core/types';
1
+ import type { ApplicationService } from '@adonisjs/core/types';
2
+ /**
3
+ * Session provider configures the session management inside an
4
+ * AdonisJS application
5
+ */
2
6
  export default class SessionProvider {
3
7
  protected app: ApplicationService;
4
8
  constructor(app: ApplicationService);
5
- /**
6
- * Register Session Manager in the container
7
- */
8
- register(): Promise<void>;
9
- /**
10
- * Register bindings
11
- */
9
+ register(): void;
12
10
  boot(): Promise<void>;
13
11
  }
@@ -6,38 +6,28 @@
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
8
8
  */
9
- import { extendHttpContext } from '../src/bindings/http_context.js';
10
- import { extendApiClient } from '../src/bindings/api_client.js';
9
+ import { registerSessionDriver } from '../src/helpers.js';
10
+ import SessionMiddleware from '../src/session_middleware.js';
11
+ /**
12
+ * Session provider configures the session management inside an
13
+ * AdonisJS application
14
+ */
11
15
  export default class SessionProvider {
12
16
  app;
13
17
  constructor(app) {
14
18
  this.app = app;
15
19
  }
16
- /**
17
- * Register Session Manager in the container
18
- */
19
- async register() {
20
- this.app.container.singleton('session', async () => {
21
- const { SessionManager } = await import('../src/session_manager.js');
22
- const encryption = await this.app.container.make('encryption');
23
- const redis = await this.app.container.make('redis').catch(() => undefined);
20
+ register() {
21
+ this.app.container.singleton(SessionMiddleware, async (resolver) => {
24
22
  const config = this.app.config.get('session', {});
25
- return new SessionManager(config, encryption, redis);
23
+ const emitter = await resolver.make('emitter');
24
+ return new SessionMiddleware(config, emitter);
26
25
  });
27
26
  }
28
- /**
29
- * Register bindings
30
- */
31
27
  async boot() {
32
- const sessionManager = await this.app.container.make('session');
33
- /**
34
- * Add `session` getter to the HttpContext class
35
- */
36
- extendHttpContext(sessionManager);
37
- /**
38
- * Add some macros and getter to japa/api-client classes for
39
- * easier testing
40
- */
41
- extendApiClient(sessionManager);
28
+ this.app.container.resolving(SessionMiddleware, async () => {
29
+ const config = this.app.config.get('session');
30
+ await registerSessionDriver(this.app, config.driver);
31
+ });
42
32
  }
43
33
  }
@@ -1,41 +1,29 @@
1
- import { Store } from './store.js';
2
- import type { SessionConfig, SessionDriverContract } from './types.js';
3
1
  import type { CookieClient } from '@adonisjs/core/http';
2
+ import type { SessionConfig, SessionData, SessionDriverContract } from './types/main.js';
4
3
  /**
5
- * SessionClient exposes the API to set session data as a client
4
+ * Session client exposes the API to set session data as a client
6
5
  */
7
- export declare class SessionClient extends Store {
6
+ export declare class SessionClient {
8
7
  #private;
9
8
  /**
10
- * Each instance of client works on a single session id. Generate
11
- * multiple client instances for a different session id
9
+ * Session key for setting flash messages
12
10
  */
13
- sessionId: string;
11
+ flashKey: string;
12
+ constructor(config: SessionConfig, driver: SessionDriverContract, cookieClient: CookieClient);
14
13
  /**
15
- * Flash messages store. They are merged with the session data during
16
- * commit
14
+ * Load session data from the driver
17
15
  */
18
- flashMessages: Store;
19
- constructor(config: SessionConfig, driver: SessionDriverContract, cookieClient: CookieClient, values: {
20
- [key: string]: any;
21
- } | null);
22
- /**
23
- * Find if the sessions are enabled
24
- */
25
- isEnabled(): boolean;
26
- /**
27
- * Load session from the driver
28
- */
29
- load(cookies: Record<string, any>): Promise<{
30
- session: any;
31
- flashMessages: any;
16
+ load(cookies: Record<string, any>, sessionId?: string): Promise<{
17
+ sessionId: string;
18
+ session: SessionData;
19
+ flashMessages: SessionData;
32
20
  }>;
33
21
  /**
34
22
  * Commits the session data to the session store and returns
35
23
  * the session id and cookie name for it to be accessible
36
24
  * by the server
37
25
  */
38
- commit(): Promise<{
26
+ commit(values: SessionData | null, flashMessages: SessionData | null, sessionId?: string): Promise<{
39
27
  sessionId: string;
40
28
  signedSessionId: string;
41
29
  cookieName: string;
@@ -43,5 +31,5 @@ export declare class SessionClient extends Store {
43
31
  /**
44
32
  * Clear the session store
45
33
  */
46
- forget(): Promise<void>;
34
+ forget(sessionId?: string): Promise<void>;
47
35
  }
@@ -9,15 +9,15 @@
9
9
  import { cuid } from '@adonisjs/core/helpers';
10
10
  import { Store } from './store.js';
11
11
  /**
12
- * SessionClient exposes the API to set session data as a client
12
+ * Session client exposes the API to set session data as a client
13
13
  */
14
- export class SessionClient extends Store {
14
+ export class SessionClient {
15
15
  /**
16
16
  * Session configuration
17
17
  */
18
18
  #config;
19
19
  /**
20
- * The session driver used to read and write session data
20
+ * The session driver to use for reading and writing session data
21
21
  */
22
22
  #driver;
23
23
  /**
@@ -25,41 +25,30 @@ export class SessionClient extends Store {
25
25
  */
26
26
  #cookieClient;
27
27
  /**
28
- * Each instance of client works on a single session id. Generate
29
- * multiple client instances for a different session id
28
+ * Session to use when no explicit session id is
29
+ * defined
30
30
  */
31
- sessionId = cuid();
31
+ #sessionId = cuid();
32
32
  /**
33
33
  * Session key for setting flash messages
34
34
  */
35
- #flashMessagesKey = '__flash__';
36
- /**
37
- * Flash messages store. They are merged with the session data during
38
- * commit
39
- */
40
- flashMessages = new Store({});
41
- constructor(config, driver, cookieClient, values) {
42
- super(values);
35
+ flashKey = '__flash__';
36
+ constructor(config, driver, cookieClient) {
43
37
  this.#config = config;
44
38
  this.#driver = driver;
45
39
  this.#cookieClient = cookieClient;
46
40
  }
47
41
  /**
48
- * Find if the sessions are enabled
49
- */
50
- isEnabled() {
51
- return this.#config.enabled;
52
- }
53
- /**
54
- * Load session from the driver
42
+ * Load session data from the driver
55
43
  */
56
- async load(cookies) {
44
+ async load(cookies, sessionId) {
57
45
  const sessionIdCookie = cookies[this.#config.cookieName];
58
- const sessionId = sessionIdCookie ? sessionIdCookie.value : this.sessionId;
59
- const contents = await this.#driver.read(sessionId);
46
+ const sessId = sessionId || sessionIdCookie ? sessionIdCookie.value : this.#sessionId;
47
+ const contents = await this.#driver.read(sessId);
60
48
  const store = new Store(contents);
61
- const flashMessages = store.pull(this.#flashMessagesKey, null);
49
+ const flashMessages = store.pull(this.flashKey, null);
62
50
  return {
51
+ sessionId: sessId,
63
52
  session: store.all(),
64
53
  flashMessages,
65
54
  };
@@ -69,32 +58,24 @@ export class SessionClient extends Store {
69
58
  * the session id and cookie name for it to be accessible
70
59
  * by the server
71
60
  */
72
- async commit() {
73
- this.set(this.#flashMessagesKey, this.flashMessages.all());
74
- await this.#driver.write(this.sessionId, this.toJSON());
61
+ async commit(values, flashMessages, sessionId) {
62
+ const sessId = sessionId || this.#sessionId;
75
63
  /**
76
- * Clear from the session client memory
64
+ * Persist session data to the store, alongside flash messages
77
65
  */
78
- this.clear();
79
- this.flashMessages.clear();
66
+ if (values || flashMessages) {
67
+ await this.#driver.write(sessId, Object.assign({ [this.flashKey]: flashMessages }, values));
68
+ }
80
69
  return {
81
- sessionId: this.sessionId,
82
- signedSessionId: this.#cookieClient.sign(this.#config.cookieName, this.sessionId),
70
+ sessionId: sessId,
71
+ signedSessionId: this.#cookieClient.sign(this.#config.cookieName, sessId),
83
72
  cookieName: this.#config.cookieName,
84
73
  };
85
74
  }
86
75
  /**
87
76
  * Clear the session store
88
77
  */
89
- async forget() {
90
- /**
91
- * Clear from the session client memory
92
- */
93
- this.clear();
94
- this.flashMessages.clear();
95
- /**
96
- * Clear with the driver
97
- */
98
- await this.#driver.destroy(this.sessionId);
78
+ async forget(sessionId) {
79
+ await this.#driver.destroy(sessionId || this.#sessionId);
99
80
  }
100
81
  }
@@ -0,0 +1,3 @@
1
+ /// <reference types="@types/node" resolution-mode="require"/>
2
+ declare const _default: import("util").DebugLogger;
3
+ export default _default;
@@ -0,0 +1,10 @@
1
+ /*
2
+ * @adonisjs/session
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ import { debuglog } from 'node:util';
10
+ export default debuglog('adonisjs:session');
@@ -1,5 +1,8 @@
1
- import { SessionConfig } from './types.js';
1
+ import type { CookieOptions } from '@adonisjs/core/types/http';
2
+ import type { SessionConfig } from './types/main.js';
2
3
  /**
3
- * Helper to define session config
4
+ * Helper to normalize session config
4
5
  */
5
- export declare function defineConfig(config: SessionConfig): SessionConfig;
6
+ export declare function defineConfig(config: Partial<SessionConfig>): SessionConfig & {
7
+ cookie: Partial<CookieOptions>;
8
+ };
@@ -1,13 +1,42 @@
1
+ /*
2
+ * @adonisjs/session
3
+ *
4
+ * (c) AdonisJS
5
+ *
6
+ * For the full copyright and license information, please view the LICENSE
7
+ * file that was distributed with this source code.
8
+ */
9
+ import string from '@poppinss/utils/string';
1
10
  import { InvalidArgumentsException } from '@poppinss/utils';
11
+ import debug from './debug.js';
2
12
  /**
3
- * Helper to define session config
13
+ * Helper to normalize session config
4
14
  */
5
15
  export function defineConfig(config) {
6
- if (!config.cookieName) {
7
- throw new InvalidArgumentsException('Missing "cookieName" property inside the session config');
8
- }
16
+ /**
17
+ * Make sure a driver is defined
18
+ */
9
19
  if (!config.driver) {
10
20
  throw new InvalidArgumentsException('Missing "driver" property inside the session config');
11
21
  }
12
- return config;
22
+ const age = config.age || '2h';
23
+ const clearWithBrowser = config.clearWithBrowser ?? false;
24
+ const cookieOptions = { ...config.cookie };
25
+ /**
26
+ * Define maxAge property when session id cookie is
27
+ * not a session cookie.
28
+ */
29
+ if (!clearWithBrowser) {
30
+ debug('computing maxAge for session id cookie');
31
+ cookieOptions.maxAge = string.seconds.parse(config.age || age);
32
+ }
33
+ return {
34
+ enabled: true,
35
+ age,
36
+ clearWithBrowser,
37
+ cookieName: 'adonis_session',
38
+ cookie: cookieOptions,
39
+ driver: config.driver,
40
+ ...config,
41
+ };
13
42
  }
@@ -1,23 +1,21 @@
1
1
  import type { HttpContext } from '@adonisjs/core/http';
2
- import type { SessionConfig, SessionDriverContract } from '../types.js';
2
+ import { CookieOptions } from '@adonisjs/core/types/http';
3
+ import type { SessionData, SessionDriverContract } from '../types/main.js';
3
4
  /**
4
- * Cookie driver utilizes the encrypted HTTP cookies to write session value.
5
+ * Cookie driver stores the session data inside an encrypted
6
+ * cookie.
5
7
  */
6
8
  export declare class CookieDriver implements SessionDriverContract {
7
9
  #private;
8
- constructor(config: SessionConfig, ctx: HttpContext);
10
+ constructor(config: Partial<CookieOptions>, ctx: HttpContext);
9
11
  /**
10
12
  * Read session value from the cookie
11
13
  */
12
- read(sessionId: string): {
13
- [key: string]: any;
14
- } | null;
14
+ read(sessionId: string): SessionData | null;
15
15
  /**
16
16
  * Write session values to the cookie
17
17
  */
18
- write(sessionId: string, values: {
19
- [key: string]: any;
20
- }): void;
18
+ write(sessionId: string, values: SessionData): void;
21
19
  /**
22
20
  * Removes the session cookie
23
21
  */
@@ -6,20 +6,24 @@
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
8
8
  */
9
+ import debug from '../debug.js';
9
10
  /**
10
- * Cookie driver utilizes the encrypted HTTP cookies to write session value.
11
+ * Cookie driver stores the session data inside an encrypted
12
+ * cookie.
11
13
  */
12
14
  export class CookieDriver {
13
- #config;
14
15
  #ctx;
16
+ #config;
15
17
  constructor(config, ctx) {
16
18
  this.#config = config;
17
19
  this.#ctx = ctx;
20
+ debug('initiating cookie driver %O', this.#config);
18
21
  }
19
22
  /**
20
23
  * Read session value from the cookie
21
24
  */
22
25
  read(sessionId) {
26
+ debug('cookie driver: reading session data %s', sessionId);
23
27
  const cookieValue = this.#ctx.request.encryptedCookie(sessionId);
24
28
  if (typeof cookieValue !== 'object') {
25
29
  return null;
@@ -30,15 +34,14 @@ export class CookieDriver {
30
34
  * Write session values to the cookie
31
35
  */
32
36
  write(sessionId, values) {
33
- if (typeof values !== 'object') {
34
- throw new Error('Session cookie driver expects an object of values');
35
- }
36
- this.#ctx.response.encryptedCookie(sessionId, values, this.#config.cookie);
37
+ debug('cookie driver: writing session data %s: %O', sessionId, values);
38
+ this.#ctx.response.encryptedCookie(sessionId, values, this.#config);
37
39
  }
38
40
  /**
39
41
  * Removes the session cookie
40
42
  */
41
43
  destroy(sessionId) {
44
+ debug('cookie driver: destroying session data %s', sessionId);
42
45
  if (this.#ctx.request.cookiesList()[sessionId]) {
43
46
  this.#ctx.response.clearCookie(sessionId);
44
47
  }
@@ -48,6 +51,7 @@ export class CookieDriver {
48
51
  */
49
52
  touch(sessionId) {
50
53
  const value = this.read(sessionId);
54
+ debug('cookie driver: touching session data %s', sessionId);
51
55
  if (!value) {
52
56
  return;
53
57
  }
@@ -6,32 +6,29 @@
6
6
  * For the full copyright and license information, please view the LICENSE
7
7
  * file that was distributed with this source code.
8
8
  */
9
- import { SessionConfig, SessionDriverContract } from '../types.js';
9
+ import type { FileDriverConfig, SessionData, SessionDriverContract } from '../types/main.js';
10
10
  /**
11
- * File driver to read/write session to filesystem
11
+ * File driver writes the session data on the file system as. Each session
12
+ * id gets its own file.
12
13
  */
13
14
  export declare class FileDriver implements SessionDriverContract {
14
15
  #private;
15
- constructor(config: SessionConfig);
16
+ constructor(config: FileDriverConfig, age: string | number);
16
17
  /**
17
- * Returns file contents. A new file will be created if it's
18
- * missing.
18
+ * Reads the session data from the disk.
19
19
  */
20
- read(sessionId: string): Promise<{
21
- [key: string]: any;
22
- } | null>;
20
+ read(sessionId: string): Promise<SessionData | null>;
23
21
  /**
24
- * Write session values to a file
22
+ * Writes the session data to the disk as a string
25
23
  */
26
- write(sessionId: string, values: {
27
- [key: string]: any;
28
- }): Promise<void>;
24
+ write(sessionId: string, values: SessionData): Promise<void>;
29
25
  /**
30
- * Cleanup session file by removing it
26
+ * Removes the session file from the disk
31
27
  */
32
28
  destroy(sessionId: string): Promise<void>;
33
29
  /**
34
- * Writes the value by reading it from the store
30
+ * Updates the session expiry by rewriting it to the
31
+ * persistence store
35
32
  */
36
33
  touch(sessionId: string): Promise<void>;
37
34
  }