@adonisjs/session 7.0.0-0 → 7.0.0-10

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 (53) hide show
  1. package/README.md +18 -38
  2. package/build/configure.js +29 -2
  3. package/build/factories/main.d.ts +1 -0
  4. package/build/factories/main.js +9 -0
  5. package/build/factories/session_middleware_factory.d.ts +22 -0
  6. package/build/factories/session_middleware_factory.js +47 -0
  7. package/build/index.d.ts +5 -3
  8. package/build/index.js +5 -3
  9. package/build/providers/session_provider.d.ts +15 -4
  10. package/build/providers/session_provider.js +37 -20
  11. package/build/src/client.d.ts +13 -25
  12. package/build/src/client.js +24 -43
  13. package/build/src/debug.d.ts +3 -0
  14. package/build/src/debug.js +10 -0
  15. package/build/src/define_config.d.ts +6 -3
  16. package/build/src/define_config.js +34 -5
  17. package/build/src/drivers/cookie.d.ts +7 -9
  18. package/build/src/drivers/cookie.js +10 -6
  19. package/build/src/drivers/file.d.ts +11 -14
  20. package/build/src/drivers/file.js +90 -34
  21. package/build/src/drivers/memory.d.ts +4 -8
  22. package/build/src/drivers/memory.js +0 -3
  23. package/build/src/drivers/redis.d.ts +4 -6
  24. package/build/src/drivers/redis.js +25 -29
  25. package/build/src/drivers_collection.d.ts +22 -0
  26. package/build/src/drivers_collection.js +38 -0
  27. package/build/src/edge_plugin_adonisjs_session.d.ts +6 -0
  28. package/build/src/edge_plugin_adonisjs_session.js +92 -0
  29. package/build/src/errors.d.ts +8 -0
  30. package/build/src/errors.js +17 -0
  31. package/build/src/helpers.d.ts +6 -0
  32. package/build/src/helpers.js +43 -0
  33. package/build/src/session.d.ts +86 -59
  34. package/build/src/session.js +235 -224
  35. package/build/src/session_middleware.d.ts +19 -2
  36. package/build/src/session_middleware.js +43 -4
  37. package/build/src/store.d.ts +48 -35
  38. package/build/src/store.js +85 -57
  39. package/build/src/types/extended.d.ts +19 -0
  40. package/build/src/types/main.d.ts +106 -0
  41. package/build/src/types/main.js +9 -0
  42. package/build/stubs/config.stub +28 -92
  43. package/package.json +37 -26
  44. package/build/src/bindings/api_client.d.ts +0 -2
  45. package/build/src/bindings/api_client.js +0 -135
  46. package/build/src/bindings/http_context.d.ts +0 -5
  47. package/build/src/bindings/http_context.js +0 -17
  48. package/build/src/bindings/types.d.ts +0 -77
  49. package/build/src/session_manager.d.ts +0 -38
  50. package/build/src/session_manager.js +0 -149
  51. package/build/src/types.d.ts +0 -61
  52. package/build/src/types.js +0 -1
  53. /package/build/src/{bindings/types.js → types/extended.js} +0 -0
@@ -1,9 +1,44 @@
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 { ExceptionHandler } from '@adonisjs/core/http';
10
+ import { Session } from './session.js';
11
+ import sessionDriversList from './drivers_collection.js';
12
+ /**
13
+ * Overwriting validation exception renderer
14
+ */
15
+ const originalErrorHandler = ExceptionHandler.prototype.renderValidationErrorAsHTML;
16
+ ExceptionHandler.macro('renderValidationErrorAsHTML', async function (error, ctx) {
17
+ if (ctx.session) {
18
+ ctx.session.flashValidationErrors(error);
19
+ ctx.response.redirect('back', true);
20
+ }
21
+ else {
22
+ return originalErrorHandler(error, ctx);
23
+ }
24
+ });
25
+ /**
26
+ * Session middleware is used to initiate the session store
27
+ * and commit its values during an HTTP request
28
+ */
1
29
  export default class SessionMiddleware {
30
+ #config;
31
+ #emitter;
32
+ constructor(config, emitter) {
33
+ this.#config = config;
34
+ this.#emitter = emitter;
35
+ }
2
36
  async handle(ctx, next) {
3
- const sessionManager = (await ctx.containerResolver.make('session'));
4
- if (!sessionManager.isEnabled()) {
5
- return;
37
+ if (!this.#config.enabled) {
38
+ return next();
6
39
  }
40
+ const driver = sessionDriversList.create(this.#config.driver, this.#config, ctx);
41
+ ctx.session = new Session(this.#config, driver, this.#emitter, ctx);
7
42
  /**
8
43
  * Initiate session store
9
44
  */
@@ -11,10 +46,14 @@ export default class SessionMiddleware {
11
46
  /**
12
47
  * Call next middlewares or route handler
13
48
  */
14
- await next();
49
+ const response = await next();
15
50
  /**
16
51
  * Commit store mutations
17
52
  */
18
53
  await ctx.session.commit();
54
+ /**
55
+ * Return response
56
+ */
57
+ return response;
19
58
  }
20
59
  }
@@ -1,32 +1,62 @@
1
- import type { AllowedSessionValues } from './types.js';
1
+ import type { AllowedSessionValues, SessionData } from './types/main.js';
2
2
  /**
3
- * Session store to mutate and access values from the session object
3
+ * Readonly session store
4
4
  */
5
- export declare class Store {
6
- #private;
7
- constructor(values: {
8
- [key: string]: any;
9
- } | null);
5
+ export declare class ReadOnlyStore {
10
6
  /**
11
- * Find if store is empty or not
7
+ * Underlying store values
12
8
  */
13
- get isEmpty(): boolean;
9
+ protected values: SessionData;
14
10
  /**
15
- * Set key/value pair
11
+ * Find if store is empty or not
16
12
  */
17
- set(key: string, value: AllowedSessionValues): void;
13
+ get isEmpty(): boolean;
14
+ constructor(values: SessionData | null);
18
15
  /**
19
16
  * Get value for a given key
20
17
  */
21
18
  get(key: string, defaultValue?: any): any;
22
19
  /**
23
- * Remove key
20
+ * A boolean to know if value exists. Extra guards to check
21
+ * arrays for it's length as well.
24
22
  */
25
- unset(key: string): void;
23
+ has(key: string, checkForArraysLength?: boolean): boolean;
26
24
  /**
27
- * Reset store by clearing it's values.
25
+ * Get all values
28
26
  */
29
- clear(): void;
27
+ all(): any;
28
+ /**
29
+ * Returns object representation of values
30
+ */
31
+ toObject(): any;
32
+ /**
33
+ * Returns the store values
34
+ */
35
+ toJSON(): any;
36
+ /**
37
+ * Returns string representation of the store
38
+ */
39
+ toString(): string;
40
+ }
41
+ /**
42
+ * Session store encapsulates the session data and offers a
43
+ * declarative API to mutate it.
44
+ */
45
+ export declare class Store extends ReadOnlyStore {
46
+ #private;
47
+ constructor(values: SessionData | null);
48
+ /**
49
+ * Find if the store has been modified.
50
+ */
51
+ get hasBeenModified(): boolean;
52
+ /**
53
+ * Set key/value pair
54
+ */
55
+ set(key: string, value: AllowedSessionValues): void;
56
+ /**
57
+ * Remove key
58
+ */
59
+ unset(key: string): void;
30
60
  /**
31
61
  * Pull value from the store. It is same as calling
32
62
  * store.get and then store.unset
@@ -43,7 +73,7 @@ export declare class Store {
43
73
  */
44
74
  decrement(key: string, steps?: number): void;
45
75
  /**
46
- * Overwrite the underlying values object
76
+ * Overwrite existing store data with new values.
47
77
  */
48
78
  update(values: {
49
79
  [key: string]: any;
@@ -55,24 +85,7 @@ export declare class Store {
55
85
  [key: string]: any;
56
86
  }): any;
57
87
  /**
58
- * A boolean to know if value exists. Extra guards to check
59
- * arrays for it's length as well.
60
- */
61
- has(key: string, checkForArraysLength?: boolean): boolean;
62
- /**
63
- * Get all values
64
- */
65
- all(): any;
66
- /**
67
- * Returns object representation of values
68
- */
69
- toObject(): any;
70
- /**
71
- * Returns the store values
72
- */
73
- toJSON(): any;
74
- /**
75
- * Returns string representation of the store
88
+ * Reset store by clearing it's values.
76
89
  */
77
- toString(): string;
90
+ clear(): void;
78
91
  }
@@ -6,48 +6,103 @@
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 { Exception } from '@poppinss/utils';
10
9
  import lodash from '@poppinss/utils/lodash';
10
+ import { RuntimeException } from '@poppinss/utils';
11
11
  /**
12
- * Session store to mutate and access values from the session object
12
+ * Readonly session store
13
13
  */
14
- export class Store {
14
+ export class ReadOnlyStore {
15
15
  /**
16
16
  * Underlying store values
17
17
  */
18
- #values;
19
- constructor(values) {
20
- this.#values = values || {};
21
- }
18
+ values;
22
19
  /**
23
20
  * Find if store is empty or not
24
21
  */
25
22
  get isEmpty() {
26
- return !this.#values || Object.keys(this.#values).length === 0;
23
+ return !this.values || Object.keys(this.values).length === 0;
27
24
  }
28
- /**
29
- * Set key/value pair
30
- */
31
- set(key, value) {
32
- lodash.set(this.#values, key, value);
25
+ constructor(values) {
26
+ this.values = values || {};
33
27
  }
34
28
  /**
35
29
  * Get value for a given key
36
30
  */
37
31
  get(key, defaultValue) {
38
- return lodash.get(this.#values, key, defaultValue);
32
+ const value = lodash.get(this.values, key);
33
+ if (defaultValue !== undefined && (value === null || value === undefined)) {
34
+ return defaultValue;
35
+ }
36
+ return value;
39
37
  }
40
38
  /**
41
- * Remove key
39
+ * A boolean to know if value exists. Extra guards to check
40
+ * arrays for it's length as well.
42
41
  */
43
- unset(key) {
44
- lodash.unset(this.#values, key);
42
+ has(key, checkForArraysLength = true) {
43
+ const value = this.get(key);
44
+ if (!Array.isArray(value)) {
45
+ return !!value;
46
+ }
47
+ return checkForArraysLength ? value.length > 0 : !!value;
45
48
  }
46
49
  /**
47
- * Reset store by clearing it's values.
50
+ * Get all values
48
51
  */
49
- clear() {
50
- this.update({});
52
+ all() {
53
+ return this.values;
54
+ }
55
+ /**
56
+ * Returns object representation of values
57
+ */
58
+ toObject() {
59
+ return this.all();
60
+ }
61
+ /**
62
+ * Returns the store values
63
+ */
64
+ toJSON() {
65
+ return this.all();
66
+ }
67
+ /**
68
+ * Returns string representation of the store
69
+ */
70
+ toString() {
71
+ return JSON.stringify(this.all());
72
+ }
73
+ }
74
+ /**
75
+ * Session store encapsulates the session data and offers a
76
+ * declarative API to mutate it.
77
+ */
78
+ export class Store extends ReadOnlyStore {
79
+ /**
80
+ * A boolean to know if store has been
81
+ * modified
82
+ */
83
+ #modified = false;
84
+ constructor(values) {
85
+ super(values);
86
+ }
87
+ /**
88
+ * Find if the store has been modified.
89
+ */
90
+ get hasBeenModified() {
91
+ return this.#modified;
92
+ }
93
+ /**
94
+ * Set key/value pair
95
+ */
96
+ set(key, value) {
97
+ this.#modified = true;
98
+ lodash.set(this.values, key, value);
99
+ }
100
+ /**
101
+ * Remove key
102
+ */
103
+ unset(key) {
104
+ this.#modified = true;
105
+ lodash.unset(this.values, key);
51
106
  }
52
107
  /**
53
108
  * Pull value from the store. It is same as calling
@@ -66,7 +121,7 @@ export class Store {
66
121
  increment(key, steps = 1) {
67
122
  const value = this.get(key, 0);
68
123
  if (typeof value !== 'number') {
69
- throw new Exception(`Cannot increment "${key}", since original value is not a number`);
124
+ throw new RuntimeException(`Cannot increment "${key}". Existing value is not a number`);
70
125
  }
71
126
  this.set(key, value + steps);
72
127
  }
@@ -77,55 +132,28 @@ export class Store {
77
132
  decrement(key, steps = 1) {
78
133
  const value = this.get(key, 0);
79
134
  if (typeof value !== 'number') {
80
- throw new Exception(`Cannot increment "${key}", since original value is not a number`);
135
+ throw new RuntimeException(`Cannot decrement "${key}". Existing value is not a number`);
81
136
  }
82
137
  this.set(key, value - steps);
83
138
  }
84
139
  /**
85
- * Overwrite the underlying values object
140
+ * Overwrite existing store data with new values.
86
141
  */
87
142
  update(values) {
88
- this.#values = values;
143
+ this.#modified = true;
144
+ this.values = values;
89
145
  }
90
146
  /**
91
147
  * Update to merge values
92
148
  */
93
149
  merge(values) {
94
- lodash.merge(this.#values, values);
95
- }
96
- /**
97
- * A boolean to know if value exists. Extra guards to check
98
- * arrays for it's length as well.
99
- */
100
- has(key, checkForArraysLength = true) {
101
- const value = this.get(key);
102
- if (!Array.isArray(value)) {
103
- return !!value;
104
- }
105
- return checkForArraysLength ? value.length > 0 : !!value;
150
+ this.#modified = true;
151
+ lodash.merge(this.values, values);
106
152
  }
107
153
  /**
108
- * Get all values
109
- */
110
- all() {
111
- return this.#values;
112
- }
113
- /**
114
- * Returns object representation of values
115
- */
116
- toObject() {
117
- return this.all();
118
- }
119
- /**
120
- * Returns the store values
121
- */
122
- toJSON() {
123
- return this.all();
124
- }
125
- /**
126
- * Returns string representation of the store
154
+ * Reset store by clearing it's values.
127
155
  */
128
- toString() {
129
- return JSON.stringify(this.all());
156
+ clear() {
157
+ this.update({});
130
158
  }
131
159
  }
@@ -0,0 +1,19 @@
1
+ import type { Session } from '../session.js';
2
+ /**
3
+ * Events emitted by the session class
4
+ */
5
+ declare module '@adonisjs/core/types' {
6
+ interface EventsList {
7
+ 'session:initiated': {
8
+ session: Session;
9
+ };
10
+ 'session:committed': {
11
+ session: Session;
12
+ };
13
+ 'session:migrated': {
14
+ fromSessionId: string;
15
+ toSessionId: string;
16
+ session: Session;
17
+ };
18
+ }
19
+ }
@@ -0,0 +1,106 @@
1
+ import type { HttpContext } from '@adonisjs/core/http';
2
+ import { RedisConnections } from '@adonisjs/redis/types';
3
+ import type { CookieOptions } from '@adonisjs/core/types/http';
4
+ import type { FileDriver } from '../drivers/file.js';
5
+ import type { RedisDriver } from '../drivers/redis.js';
6
+ import type { MemoryDriver } from '../drivers/memory.js';
7
+ import type { CookieDriver } from '../drivers/cookie.js';
8
+ /**
9
+ * The values allowed by the `session.put` method
10
+ */
11
+ export type AllowedSessionValues = string | boolean | number | object | Date | Array<any>;
12
+ export type SessionData = Record<string, AllowedSessionValues>;
13
+ /**
14
+ * Session drivers must implement the session driver contract.
15
+ */
16
+ export interface SessionDriverContract {
17
+ /**
18
+ * The read method is used to read the data from the persistence
19
+ * store and return it back as an object
20
+ */
21
+ read(sessionId: string): Promise<SessionData | null> | SessionData | null;
22
+ /**
23
+ * The write method is used to write the session data into the
24
+ * persistence store.
25
+ */
26
+ write(sessionId: string, data: SessionData): Promise<void> | void;
27
+ /**
28
+ * The destroy method is used to destroy the session by removing
29
+ * its data from the persistence store
30
+ */
31
+ destroy(sessionId: string): Promise<void> | void;
32
+ /**
33
+ * The touch method should update the lifetime of session id without
34
+ * making changes to the session data.
35
+ */
36
+ touch(sessionId: string): Promise<void> | void;
37
+ }
38
+ /**
39
+ * Shape of session config.
40
+ */
41
+ export interface SessionConfig {
42
+ /**
43
+ * Enable/disable sessions temporarily
44
+ */
45
+ enabled: boolean;
46
+ /**
47
+ * The drivers to use
48
+ */
49
+ driver: keyof SessionDriversList;
50
+ /**
51
+ * The name of the cookie for storing the session id.
52
+ */
53
+ cookieName: string;
54
+ /**
55
+ * When set to true, the session id cookie will be removed
56
+ * when the user closes the browser.
57
+ *
58
+ * However, the persisted data will continue to exist until
59
+ * it gets expired.
60
+ */
61
+ clearWithBrowser: boolean;
62
+ /**
63
+ * How long the session data should be kept alive without any
64
+ * activity.
65
+ *
66
+ * The session id cookie will also live for the same duration, unless
67
+ * "clearWithBrowser" is enabled
68
+ *
69
+ * The value should be a time expression or a number in seconds
70
+ */
71
+ age: string | number;
72
+ /**
73
+ * Configuration used by the cookie driver and for storing the
74
+ * session id cookie.
75
+ */
76
+ cookie: Omit<Partial<CookieOptions>, 'maxAge' | 'expires'>;
77
+ }
78
+ /**
79
+ * Configuration used by the file driver.
80
+ */
81
+ export type FileDriverConfig = {
82
+ location: string;
83
+ };
84
+ /**
85
+ * Configuration used by the redis driver.
86
+ */
87
+ export type RedisDriverConfig = {
88
+ connection: keyof RedisConnections;
89
+ };
90
+ /**
91
+ * Extending session config with the drivers config
92
+ */
93
+ export interface SessionConfig {
94
+ file?: FileDriverConfig;
95
+ redis?: RedisDriverConfig;
96
+ }
97
+ /**
98
+ * List of the session drivers. The list can be extended using
99
+ * declaration merging
100
+ */
101
+ export interface SessionDriversList {
102
+ file: (config: SessionConfig, ctx: HttpContext) => FileDriver;
103
+ cookie: (config: SessionConfig, ctx: HttpContext) => CookieDriver;
104
+ redis: (config: SessionConfig, ctx: HttpContext) => RedisDriver;
105
+ memory: (config: SessionConfig, ctx: HttpContext) => MemoryDriver;
106
+ }
@@ -0,0 +1,9 @@
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
+ export {};
@@ -1,113 +1,49 @@
1
1
  ---
2
2
  to: {{ app.configPath('session.ts') }}
3
3
  ---
4
-
5
4
  import env from '#start/env'
6
- import app from '@adonisjs/core/services/app'
7
5
  import { defineConfig } from '@adonisjs/session'
8
6
 
9
7
  export default defineConfig({
10
- /*
11
- |--------------------------------------------------------------------------
12
- | Enable/Disable sessions
13
- |--------------------------------------------------------------------------
14
- |
15
- | Setting the following property to "false" will disable the session for the
16
- | entire application
17
- |
18
- */
19
8
  enabled: true,
20
-
21
- /*
22
- |--------------------------------------------------------------------------
23
- | Driver
24
- |--------------------------------------------------------------------------
25
- |
26
- | The session driver to use. You can choose between one of the following
27
- | drivers.
28
- |
29
- | - cookie (Uses signed cookies to store session values)
30
- | - file (Uses filesystem to store session values)
31
- | - redis (Uses redis. Make sure to install "@adonisjs/redis" as well)
32
- |
33
- | Note: Switching drivers will make existing sessions invalid.
34
- |
35
- */
36
- driver: env.get('SESSION_DRIVER'),
37
-
38
- /*
39
- |--------------------------------------------------------------------------
40
- | Cookie name
41
- |--------------------------------------------------------------------------
42
- |
43
- | The name of the cookie that will hold the session id.
44
- |
45
- */
46
9
  cookieName: 'adonis-session',
47
10
 
48
- /*
49
- |--------------------------------------------------------------------------
50
- | Clear session when browser closes
51
- |--------------------------------------------------------------------------
52
- |
53
- | Whether or not you want to destroy the session when browser closes. Setting
54
- | this value to "true" will ignore the "age".
55
- |
56
- */
11
+ /**
12
+ * When set to true, the session id cookie will be deleted
13
+ * once the user closes the browser.
14
+ */
57
15
  clearWithBrowser: false,
58
16
 
59
- /*
60
- |--------------------------------------------------------------------------
61
- | Session age
62
- |--------------------------------------------------------------------------
63
- |
64
- | The duration for which session stays active after no activity. A new HTTP
65
- | request to the server is considered as activity.
66
- |
67
- | The value can be a number in milliseconds or a string that must be valid
68
- | as per https://npmjs.org/package/ms package.
69
- |
70
- | Example: "2 days", "2.5 hrs", "1y", "5s" and so on.
71
- |
72
- */
17
+ /**
18
+ * Define how long to keep the session data alive without
19
+ * any activity.
20
+ */
73
21
  age: '2h',
74
22
 
75
- /*
76
- |--------------------------------------------------------------------------
77
- | Cookie values
78
- |--------------------------------------------------------------------------
79
- |
80
- | The cookie settings are used to setup the session id cookie and also the
81
- | driver will use the same values.
82
- |
83
- */
23
+ /**
24
+ * The driver to use. Make sure to validate the environment
25
+ * variable in order to infer the driver name without any
26
+ * errors.
27
+ */
28
+ driver: env.get('SESSION_DRIVER'),
29
+
84
30
  cookie: {
85
31
  path: '/',
86
32
  httpOnly: true,
87
33
  sameSite: false,
88
34
  },
89
35
 
90
- /*
91
- |--------------------------------------------------------------------------
92
- | Configuration for the file driver
93
- |--------------------------------------------------------------------------
94
- |
95
- | The file driver needs absolute path to the directory in which sessions
96
- | must be stored.
97
- |
98
- */
99
- file: {
100
- location: app.tmpPath('sessions'),
101
- },
102
-
103
- /*
104
- |--------------------------------------------------------------------------
105
- | Redis driver
106
- |--------------------------------------------------------------------------
107
- |
108
- | The redis connection you want session driver to use. The same connection
109
- | must be defined inside "config/redis.ts" file as well.
110
- |
111
- */
112
- redisConnection: 'local',
36
+ /**
37
+ * Settings for the file driver
38
+ */
39
+ // file: {
40
+ // location: app.tmpPath('sessions'),
41
+ // },
42
+
43
+ /**
44
+ * Settings for the redis driver
45
+ */
46
+ // redis: {
47
+ // connection: 'main'
48
+ // },
113
49
  })