@adonisjs/session 7.0.0-2 → 7.0.0-4
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 +5 -8
- package/build/index.d.ts +5 -3
- package/build/index.js +5 -3
- package/build/providers/session_provider.d.ts +5 -8
- package/build/providers/session_provider.js +13 -35
- package/build/src/client.d.ts +13 -25
- package/build/src/client.js +24 -43
- package/build/src/debug.d.ts +3 -0
- package/build/src/debug.js +10 -0
- package/build/src/define_config.d.ts +6 -3
- package/build/src/define_config.js +34 -5
- package/build/src/drivers/cookie.d.ts +7 -9
- package/build/src/drivers/cookie.js +10 -6
- package/build/src/drivers/file.d.ts +11 -14
- package/build/src/drivers/file.js +65 -42
- package/build/src/drivers/memory.d.ts +4 -8
- package/build/src/drivers/memory.js +0 -3
- package/build/src/drivers/redis.d.ts +4 -6
- package/build/src/drivers/redis.js +25 -29
- package/build/src/drivers_collection.d.ts +22 -0
- package/build/src/drivers_collection.js +38 -0
- package/build/src/errors.d.ts +8 -0
- package/build/src/errors.js +17 -0
- package/build/src/helpers.d.ts +6 -0
- package/build/src/helpers.js +43 -0
- package/build/src/session.d.ts +86 -59
- package/build/src/session.js +221 -221
- package/build/src/session_middleware.d.ts +19 -5
- package/build/src/session_middleware.js +42 -6
- package/build/src/store.d.ts +17 -14
- package/build/src/store.js +33 -17
- package/build/src/types/extended.d.ts +19 -0
- package/build/src/types/main.d.ts +106 -0
- package/build/src/types/main.js +9 -0
- package/build/stubs/config.stub +28 -90
- package/package.json +23 -20
- package/build/src/bindings/api_client.d.ts +0 -2
- package/build/src/bindings/api_client.js +0 -135
- package/build/src/bindings/http_context.d.ts +0 -5
- package/build/src/bindings/http_context.js +0 -17
- package/build/src/bindings/types.d.ts +0 -77
- package/build/src/session_manager.d.ts +0 -38
- package/build/src/session_manager.js +0 -149
- package/build/src/types.d.ts +0 -61
- package/build/src/types.js +0 -1
- /package/build/src/{bindings/types.js → types/extended.js} +0 -0
package/build/src/session.js
CHANGED
|
@@ -6,366 +6,366 @@
|
|
|
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';
|
|
11
10
|
import { cuid } from '@adonisjs/core/helpers';
|
|
12
11
|
import { Store } from './store.js';
|
|
12
|
+
import * as errors from './errors.js';
|
|
13
|
+
import debug from './debug.js';
|
|
13
14
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
15
|
+
* The session class exposes the API to read and write values to
|
|
16
|
+
* the session store.
|
|
17
|
+
*
|
|
18
|
+
* A session instance is isolated between requests but
|
|
19
|
+
* uses a centralized persistence store and
|
|
16
20
|
*/
|
|
17
21
|
export class Session {
|
|
18
|
-
/**
|
|
19
|
-
* Session id for the current request. It will be different
|
|
20
|
-
* from the "this.sessionId" when regenerate is called.
|
|
21
|
-
*/
|
|
22
|
-
#currentSessionId;
|
|
23
|
-
/**
|
|
24
|
-
* A instance of store with values read from the driver. The store
|
|
25
|
-
* in initiated inside the [[initiate]] method
|
|
26
|
-
*/
|
|
27
|
-
#store;
|
|
28
|
-
/**
|
|
29
|
-
* Whether or not to re-generate the session id before committing
|
|
30
|
-
* session values.
|
|
31
|
-
*/
|
|
32
|
-
#regeneratedSessionId = false;
|
|
33
|
-
/**
|
|
34
|
-
* Session key for setting flash messages
|
|
35
|
-
*/
|
|
36
|
-
#flashMessagesKey = '__flash__';
|
|
37
|
-
/**
|
|
38
|
-
* The HTTP context for the current request.
|
|
39
|
-
*/
|
|
40
|
-
#ctx;
|
|
41
|
-
/**
|
|
42
|
-
* Configuration for the session
|
|
43
|
-
*/
|
|
44
22
|
#config;
|
|
45
|
-
/**
|
|
46
|
-
* The session driver instance used to read and write session data.
|
|
47
|
-
*/
|
|
48
23
|
#driver;
|
|
24
|
+
#emitter;
|
|
25
|
+
#ctx;
|
|
26
|
+
#readonly = false;
|
|
27
|
+
#store;
|
|
49
28
|
/**
|
|
50
|
-
*
|
|
51
|
-
|
|
52
|
-
initiated = false;
|
|
53
|
-
/**
|
|
54
|
-
* A boolean to know if it's a fresh session or not. Fresh
|
|
55
|
-
* sessions are those, whose session id is not present
|
|
56
|
-
* in cookie
|
|
29
|
+
* Session id refers to the session id that will be committed
|
|
30
|
+
* as a cookie during the response.
|
|
57
31
|
*/
|
|
58
|
-
|
|
32
|
+
#sessionId;
|
|
59
33
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
34
|
+
* Session id from cookie refers to the value we read from the
|
|
35
|
+
* cookie during the HTTP request.
|
|
36
|
+
*
|
|
37
|
+
* This only might not exist during the first request. Also during
|
|
38
|
+
* session id re-generation, this value will be different from
|
|
39
|
+
* the session id.
|
|
62
40
|
*/
|
|
63
|
-
|
|
41
|
+
#sessionIdFromCookie;
|
|
64
42
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
43
|
+
* Store of flash messages that be written during the
|
|
44
|
+
* HTTP request
|
|
67
45
|
*/
|
|
68
|
-
|
|
46
|
+
responseFlashMessages = new Store({});
|
|
69
47
|
/**
|
|
70
|
-
*
|
|
48
|
+
* Store of flash messages for the current HTTP request.
|
|
71
49
|
*/
|
|
72
50
|
flashMessages = new Store({});
|
|
73
51
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* methods are used.
|
|
77
|
-
*
|
|
78
|
-
* The `others` object is expanded with each call.
|
|
52
|
+
* The key to use for storing flash messages inside
|
|
53
|
+
* the session store.
|
|
79
54
|
*/
|
|
80
|
-
|
|
81
|
-
constructor(ctx, config, driver) {
|
|
82
|
-
this.#ctx = ctx;
|
|
83
|
-
this.#config = config;
|
|
84
|
-
this.#driver = driver;
|
|
85
|
-
this.sessionId = this.#getSessionId();
|
|
86
|
-
this.#currentSessionId = this.sessionId;
|
|
87
|
-
}
|
|
55
|
+
flashKey = '__flash__';
|
|
88
56
|
/**
|
|
89
|
-
*
|
|
90
|
-
* when nothing is set
|
|
57
|
+
* Session id for the current HTTP request
|
|
91
58
|
*/
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
const { input, ...others } = this.responseFlashMessages.all();
|
|
97
|
-
this.put(this.#flashMessagesKey, { ...input, ...others });
|
|
59
|
+
get sessionId() {
|
|
60
|
+
return this.#sessionId;
|
|
98
61
|
}
|
|
99
62
|
/**
|
|
100
|
-
*
|
|
63
|
+
* A boolean to know if a fresh session is created during
|
|
64
|
+
* the request
|
|
101
65
|
*/
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
if (sessionId) {
|
|
105
|
-
return sessionId;
|
|
106
|
-
}
|
|
107
|
-
this.fresh = true;
|
|
108
|
-
return cuid();
|
|
66
|
+
get fresh() {
|
|
67
|
+
return this.#sessionIdFromCookie === undefined;
|
|
109
68
|
}
|
|
110
69
|
/**
|
|
111
|
-
*
|
|
70
|
+
* A boolean to know if session is in readonly
|
|
71
|
+
* state
|
|
112
72
|
*/
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
throw new Exception('Session store is not initiated yet. Make sure you are using the session hook', { code: 'E_RUNTIME_EXCEPTION', status: 500 });
|
|
116
|
-
}
|
|
73
|
+
get readonly() {
|
|
74
|
+
return this.#readonly;
|
|
117
75
|
}
|
|
118
76
|
/**
|
|
119
|
-
*
|
|
77
|
+
* A boolean to know if session store has been initiated
|
|
120
78
|
*/
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
throw new Exception('Session store is in readonly mode and cannot be mutated', {
|
|
124
|
-
status: 500,
|
|
125
|
-
code: 'E_RUNTIME_EXCEPTION',
|
|
126
|
-
});
|
|
127
|
-
}
|
|
79
|
+
get initiated() {
|
|
80
|
+
return !!this.#store;
|
|
128
81
|
}
|
|
129
82
|
/**
|
|
130
|
-
*
|
|
83
|
+
* A boolean to know if the session id has been re-generated
|
|
84
|
+
* during the current request
|
|
131
85
|
*/
|
|
132
|
-
|
|
133
|
-
this.#
|
|
134
|
-
this.#ctx.response.cookie(this.#config.cookieName, this.sessionId, this.#config.cookie);
|
|
86
|
+
get hasRegeneratedSession() {
|
|
87
|
+
return !!(this.#sessionIdFromCookie && this.#sessionIdFromCookie !== this.#sessionId);
|
|
135
88
|
}
|
|
136
89
|
/**
|
|
137
|
-
*
|
|
90
|
+
* A boolean to know if the session store is empty
|
|
138
91
|
*/
|
|
139
|
-
|
|
140
|
-
this.#
|
|
141
|
-
await this.#driver.write(this.sessionId, this.#store.toJSON());
|
|
92
|
+
get isEmpty() {
|
|
93
|
+
return this.#store?.isEmpty ?? true;
|
|
142
94
|
}
|
|
143
95
|
/**
|
|
144
|
-
*
|
|
96
|
+
* A boolean to know if the session store has been
|
|
97
|
+
* modified
|
|
145
98
|
*/
|
|
146
|
-
|
|
147
|
-
this.#
|
|
148
|
-
|
|
99
|
+
get hasBeenModified() {
|
|
100
|
+
return this.#store?.hasBeenModified ?? false;
|
|
101
|
+
}
|
|
102
|
+
constructor(config, driver, emitter, ctx) {
|
|
103
|
+
this.#ctx = ctx;
|
|
104
|
+
this.#config = config;
|
|
105
|
+
this.#driver = driver;
|
|
106
|
+
this.#emitter = emitter;
|
|
107
|
+
this.#sessionIdFromCookie = ctx.request.cookie(config.cookieName, undefined);
|
|
108
|
+
this.#sessionId = this.#sessionIdFromCookie || cuid();
|
|
149
109
|
}
|
|
150
110
|
/**
|
|
151
|
-
*
|
|
152
|
-
*
|
|
111
|
+
* Returns the flash messages store for a given
|
|
112
|
+
* mode
|
|
153
113
|
*/
|
|
154
|
-
#
|
|
155
|
-
if (this
|
|
156
|
-
|
|
114
|
+
#getFlashStore(mode) {
|
|
115
|
+
if (!this.#store) {
|
|
116
|
+
throw new errors.E_SESSION_NOT_READY();
|
|
117
|
+
}
|
|
118
|
+
if (mode === 'write' && this.readonly) {
|
|
119
|
+
throw new errors.E_SESSION_NOT_MUTABLE();
|
|
157
120
|
}
|
|
158
|
-
this.
|
|
121
|
+
return this.responseFlashMessages;
|
|
159
122
|
}
|
|
160
123
|
/**
|
|
161
|
-
*
|
|
162
|
-
* (only when view property exists)
|
|
124
|
+
* Returns the store instance for a given mode
|
|
163
125
|
*/
|
|
164
|
-
#
|
|
165
|
-
if (!this.#
|
|
166
|
-
|
|
126
|
+
#getStore(mode) {
|
|
127
|
+
if (!this.#store) {
|
|
128
|
+
throw new errors.E_SESSION_NOT_READY();
|
|
129
|
+
}
|
|
130
|
+
if (mode === 'write' && this.readonly) {
|
|
131
|
+
throw new errors.E_SESSION_NOT_MUTABLE();
|
|
167
132
|
}
|
|
168
|
-
this.#
|
|
169
|
-
flashMessages: this.flashMessages,
|
|
170
|
-
session: {
|
|
171
|
-
get: this.get.bind(this),
|
|
172
|
-
has: this.has.bind(this),
|
|
173
|
-
all: this.all.bind(this),
|
|
174
|
-
},
|
|
175
|
-
});
|
|
133
|
+
return this.#store;
|
|
176
134
|
}
|
|
177
135
|
/**
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* Multiple calls to `initiate` results in a noop.
|
|
136
|
+
* Initiates the session store. The method results in a noop
|
|
137
|
+
* when called multiple times
|
|
182
138
|
*/
|
|
183
139
|
async initiate(readonly) {
|
|
184
|
-
if (this
|
|
140
|
+
if (this.#store) {
|
|
185
141
|
return;
|
|
186
142
|
}
|
|
187
|
-
|
|
188
|
-
|
|
143
|
+
debug('initiating session (readonly: %s)', readonly);
|
|
144
|
+
this.#readonly = readonly;
|
|
145
|
+
const contents = await this.#driver.read(this.#sessionId);
|
|
189
146
|
this.#store = new Store(contents);
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Extract flash messages from the store and keep a local
|
|
149
|
+
* copy of it.
|
|
150
|
+
*/
|
|
151
|
+
if (this.has(this.flashKey)) {
|
|
152
|
+
debug('reading flash data');
|
|
153
|
+
if (this.#readonly) {
|
|
154
|
+
this.flashMessages.update(this.get(this.flashKey, null));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
this.flashMessages.update(this.pull(this.flashKey, null));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
this.#emitter.emit('session:initiated', { session: this });
|
|
202
161
|
}
|
|
203
162
|
/**
|
|
204
|
-
*
|
|
163
|
+
* Put a key-value pair to the session data store
|
|
205
164
|
*/
|
|
206
165
|
put(key, value) {
|
|
207
|
-
this.#
|
|
208
|
-
this.#ensureIsMutable();
|
|
209
|
-
this.#store.set(key, value);
|
|
166
|
+
this.#getStore('write').set(key, value);
|
|
210
167
|
}
|
|
211
168
|
/**
|
|
212
|
-
*
|
|
169
|
+
* Check if a key exists inside the datastore
|
|
213
170
|
*/
|
|
214
171
|
has(key) {
|
|
215
|
-
this.#
|
|
216
|
-
return this.#store.has(key);
|
|
172
|
+
return this.#getStore('read').has(key);
|
|
217
173
|
}
|
|
218
174
|
/**
|
|
219
|
-
* Get value from the session.
|
|
220
|
-
*
|
|
175
|
+
* Get the value of a key from the session datastore.
|
|
176
|
+
* You can specify a default value to use, when key
|
|
177
|
+
* does not exists or has undefined value.
|
|
221
178
|
*/
|
|
222
179
|
get(key, defaultValue) {
|
|
223
|
-
this.#
|
|
224
|
-
return this.#store.get(key, defaultValue);
|
|
180
|
+
return this.#getStore('read').get(key, defaultValue);
|
|
225
181
|
}
|
|
226
182
|
/**
|
|
227
|
-
*
|
|
183
|
+
* Get everything from the session store
|
|
228
184
|
*/
|
|
229
185
|
all() {
|
|
230
|
-
this.#
|
|
231
|
-
return this.#store.all();
|
|
186
|
+
return this.#getStore('read').all();
|
|
232
187
|
}
|
|
233
188
|
/**
|
|
234
|
-
* Remove
|
|
189
|
+
* Remove a key from the session datastore
|
|
235
190
|
*/
|
|
236
191
|
forget(key) {
|
|
237
|
-
this.#
|
|
238
|
-
this.#ensureIsMutable();
|
|
239
|
-
this.#store.unset(key);
|
|
192
|
+
return this.#getStore('write').unset(key);
|
|
240
193
|
}
|
|
241
194
|
/**
|
|
242
|
-
*
|
|
243
|
-
*
|
|
195
|
+
* Read value for a key from the session datastore
|
|
196
|
+
* and remove it simultaneously.
|
|
244
197
|
*/
|
|
245
198
|
pull(key, defaultValue) {
|
|
246
|
-
this.#
|
|
247
|
-
this.#ensureIsMutable();
|
|
248
|
-
return this.#store.pull(key, defaultValue);
|
|
199
|
+
return this.#getStore('write').pull(key, defaultValue);
|
|
249
200
|
}
|
|
250
201
|
/**
|
|
251
|
-
* Increment value
|
|
252
|
-
*
|
|
253
|
-
*
|
|
202
|
+
* Increment the value of a key inside the session
|
|
203
|
+
* store.
|
|
204
|
+
*
|
|
205
|
+
* A new key will be defined if does not exists already.
|
|
206
|
+
* The value of a new key will be 1
|
|
254
207
|
*/
|
|
255
208
|
increment(key, steps = 1) {
|
|
256
|
-
this.#
|
|
257
|
-
this.#ensureIsMutable();
|
|
258
|
-
this.#store.increment(key, steps);
|
|
209
|
+
return this.#getStore('write').increment(key, steps);
|
|
259
210
|
}
|
|
260
211
|
/**
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
212
|
+
* Increment the value of a key inside the session
|
|
213
|
+
* store.
|
|
214
|
+
*
|
|
215
|
+
* A new key will be defined if does not exists already.
|
|
216
|
+
* The value of a new key will be -1
|
|
264
217
|
*/
|
|
265
218
|
decrement(key, steps = 1) {
|
|
266
|
-
this.#
|
|
267
|
-
this.#ensureIsMutable();
|
|
268
|
-
this.#store.decrement(key, steps);
|
|
219
|
+
return this.#getStore('write').decrement(key, steps);
|
|
269
220
|
}
|
|
270
221
|
/**
|
|
271
|
-
*
|
|
222
|
+
* Empty the session store
|
|
272
223
|
*/
|
|
273
224
|
clear() {
|
|
274
|
-
this.#
|
|
275
|
-
this.#ensureIsMutable();
|
|
276
|
-
this.#store.clear();
|
|
225
|
+
return this.#getStore('write').clear();
|
|
277
226
|
}
|
|
278
227
|
/**
|
|
279
|
-
*
|
|
228
|
+
* Flash validation error messages. Make sure the error
|
|
229
|
+
* is an instance of VineJS ValidationException
|
|
280
230
|
*/
|
|
231
|
+
flashValidationErrors(error) {
|
|
232
|
+
const errorsBag = error.messages.reduce((result, message) => {
|
|
233
|
+
if (result[message.field]) {
|
|
234
|
+
result[message.field].push(message.message);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
result[message.field] = [message.message];
|
|
238
|
+
}
|
|
239
|
+
return result;
|
|
240
|
+
}, {});
|
|
241
|
+
this.flashExcept(['_csrf', '_method']);
|
|
242
|
+
this.flash('errors', errorsBag);
|
|
243
|
+
}
|
|
281
244
|
flash(key, value) {
|
|
282
|
-
this.#ensureIsReady();
|
|
283
|
-
this.#ensureIsMutable();
|
|
284
|
-
/**
|
|
285
|
-
* Update value
|
|
286
|
-
*/
|
|
287
245
|
if (typeof key === 'string') {
|
|
288
246
|
if (value) {
|
|
289
|
-
this.
|
|
247
|
+
this.#getFlashStore('write').set(key, value);
|
|
290
248
|
}
|
|
291
249
|
}
|
|
292
250
|
else {
|
|
293
|
-
this.
|
|
251
|
+
this.#getFlashStore('write').merge(key);
|
|
294
252
|
}
|
|
295
253
|
}
|
|
296
254
|
/**
|
|
297
|
-
* Flash
|
|
255
|
+
* Flash form input data to the flash messages store
|
|
298
256
|
*/
|
|
299
257
|
flashAll() {
|
|
300
|
-
this.#
|
|
301
|
-
this.#ensureIsMutable();
|
|
302
|
-
this.responseFlashMessages.set('input', this.#ctx.request.original());
|
|
258
|
+
return this.#getFlashStore('write').set('input', this.#ctx.request.original());
|
|
303
259
|
}
|
|
304
260
|
/**
|
|
305
|
-
* Flash
|
|
261
|
+
* Flash form input data (except some keys) to the flash messages store
|
|
306
262
|
*/
|
|
307
263
|
flashExcept(keys) {
|
|
308
|
-
this.#
|
|
309
|
-
this.#ensureIsMutable();
|
|
310
|
-
this.responseFlashMessages.set('input', lodash.omit(this.#ctx.request.original(), keys));
|
|
264
|
+
this.#getFlashStore('write').set('input', lodash.omit(this.#ctx.request.original(), keys));
|
|
311
265
|
}
|
|
312
266
|
/**
|
|
313
|
-
* Flash only
|
|
267
|
+
* Flash form input data (only some keys) to the flash messages store
|
|
314
268
|
*/
|
|
315
269
|
flashOnly(keys) {
|
|
316
|
-
this.#
|
|
317
|
-
this.#ensureIsMutable();
|
|
318
|
-
this.responseFlashMessages.set('input', lodash.pick(this.#ctx.request.original(), keys));
|
|
270
|
+
this.#getFlashStore('write').set('input', lodash.pick(this.#ctx.request.original(), keys));
|
|
319
271
|
}
|
|
320
272
|
/**
|
|
321
|
-
* Reflash
|
|
273
|
+
* Reflash messages from the last request in the current response
|
|
322
274
|
*/
|
|
323
275
|
reflash() {
|
|
324
|
-
this.
|
|
276
|
+
this.#getFlashStore('write').set('reflashed', this.flashMessages.all());
|
|
325
277
|
}
|
|
326
278
|
/**
|
|
327
|
-
* Reflash
|
|
279
|
+
* Reflash messages (only some keys) from the last
|
|
280
|
+
* request in the current response
|
|
328
281
|
*/
|
|
329
282
|
reflashOnly(keys) {
|
|
330
|
-
this.
|
|
283
|
+
this.#getFlashStore('write').set('reflashed', lodash.pick(this.flashMessages.all(), keys));
|
|
331
284
|
}
|
|
332
285
|
/**
|
|
333
|
-
*
|
|
334
|
-
*
|
|
286
|
+
* Reflash messages (except some keys) from the last
|
|
287
|
+
* request in the current response
|
|
335
288
|
*/
|
|
336
289
|
reflashExcept(keys) {
|
|
337
|
-
this.
|
|
290
|
+
this.#getFlashStore('write').set('reflashed', lodash.omit(this.flashMessages.all(), keys));
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Re-generate the session id and migrate data to it.
|
|
294
|
+
*/
|
|
295
|
+
regenerate() {
|
|
296
|
+
this.#sessionId = cuid();
|
|
338
297
|
}
|
|
339
298
|
/**
|
|
340
|
-
*
|
|
299
|
+
* Commit session changes. No more mutations will be
|
|
300
|
+
* allowed after commit.
|
|
341
301
|
*/
|
|
342
302
|
async commit() {
|
|
343
|
-
if (!this.
|
|
344
|
-
this.#touchSessionCookie();
|
|
345
|
-
await this.#touchDriver();
|
|
303
|
+
if (!this.#store || this.readonly) {
|
|
346
304
|
return;
|
|
347
305
|
}
|
|
348
306
|
/**
|
|
349
|
-
*
|
|
307
|
+
* If the flash messages store is not empty, we should put
|
|
308
|
+
* its messages inside main session store.
|
|
350
309
|
*/
|
|
351
|
-
if (this
|
|
352
|
-
|
|
310
|
+
if (!this.responseFlashMessages.isEmpty) {
|
|
311
|
+
const { input, reflashed, ...others } = this.responseFlashMessages.all();
|
|
312
|
+
this.put(this.flashKey, { ...reflashed, ...input, ...others });
|
|
353
313
|
}
|
|
314
|
+
debug('committing session data');
|
|
354
315
|
/**
|
|
355
|
-
* Touch the session cookie to
|
|
316
|
+
* Touch the session id cookie to stay alive
|
|
356
317
|
*/
|
|
357
|
-
this.#
|
|
358
|
-
this.#setFlashMessages();
|
|
318
|
+
this.#ctx.response.cookie(this.#config.cookieName, this.#sessionId, this.#config.cookie);
|
|
359
319
|
/**
|
|
360
|
-
*
|
|
361
|
-
*
|
|
362
|
-
*
|
|
320
|
+
* Delete the session data when the session store
|
|
321
|
+
* is empty.
|
|
322
|
+
*
|
|
323
|
+
* Also we only destroy the session id we read from the cookie.
|
|
324
|
+
* If there was no session id in the cookie, there won't be
|
|
325
|
+
* any data inside the store either.
|
|
363
326
|
*/
|
|
364
|
-
if (
|
|
365
|
-
|
|
327
|
+
if (this.isEmpty) {
|
|
328
|
+
if (this.#sessionIdFromCookie) {
|
|
329
|
+
await this.#driver.destroy(this.#sessionIdFromCookie);
|
|
330
|
+
}
|
|
331
|
+
this.#emitter.emit('session:committed', { session: this });
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Touch the store expiry when the session store was
|
|
336
|
+
* not modified.
|
|
337
|
+
*/
|
|
338
|
+
if (!this.hasBeenModified) {
|
|
339
|
+
if (this.#sessionIdFromCookie && this.#sessionIdFromCookie !== this.#sessionId) {
|
|
340
|
+
await this.#driver.destroy(this.#sessionIdFromCookie);
|
|
341
|
+
await this.#driver.write(this.#sessionId, this.#store.toJSON());
|
|
342
|
+
this.#emitter.emit('session:migrated', {
|
|
343
|
+
fromSessionId: this.#sessionIdFromCookie,
|
|
344
|
+
toSessionId: this.sessionId,
|
|
345
|
+
session: this,
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
await this.#driver.touch(this.#sessionId);
|
|
350
|
+
}
|
|
351
|
+
this.#emitter.emit('session:committed', { session: this });
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* Otherwise commit to the session store
|
|
356
|
+
*/
|
|
357
|
+
if (this.#sessionIdFromCookie && this.#sessionIdFromCookie !== this.#sessionId) {
|
|
358
|
+
await this.#driver.destroy(this.#sessionIdFromCookie);
|
|
359
|
+
await this.#driver.write(this.#sessionId, this.#store.toJSON());
|
|
360
|
+
this.#emitter.emit('session:migrated', {
|
|
361
|
+
fromSessionId: this.#sessionIdFromCookie,
|
|
362
|
+
toSessionId: this.sessionId,
|
|
363
|
+
session: this,
|
|
364
|
+
});
|
|
366
365
|
}
|
|
367
366
|
else {
|
|
368
|
-
await this.#driver.
|
|
367
|
+
await this.#driver.write(this.#sessionId, this.#store.toJSON());
|
|
369
368
|
}
|
|
369
|
+
this.#emitter.emit('session:committed', { session: this });
|
|
370
370
|
}
|
|
371
371
|
}
|
|
@@ -1,8 +1,22 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { EmitterService } from '@adonisjs/core/types';
|
|
2
2
|
import type { NextFn } from '@adonisjs/core/types/http';
|
|
3
|
-
import {
|
|
3
|
+
import { HttpContext } from '@adonisjs/core/http';
|
|
4
|
+
import { Session } from './session.js';
|
|
5
|
+
import type { SessionConfig } from './types/main.js';
|
|
6
|
+
/**
|
|
7
|
+
* HttpContext augmentations
|
|
8
|
+
*/
|
|
9
|
+
declare module '@adonisjs/core/http' {
|
|
10
|
+
interface HttpContext {
|
|
11
|
+
session: Session;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Session middleware is used to initiate the session store
|
|
16
|
+
* and commit its values during an HTTP request
|
|
17
|
+
*/
|
|
4
18
|
export default class SessionMiddleware {
|
|
5
|
-
|
|
6
|
-
constructor(
|
|
7
|
-
handle(ctx: HttpContext, next: NextFn): Promise<
|
|
19
|
+
#private;
|
|
20
|
+
constructor(config: SessionConfig, emitter: EmitterService);
|
|
21
|
+
handle(ctx: HttpContext, next: NextFn): Promise<any>;
|
|
8
22
|
}
|