@eggjs/session 4.0.0

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 (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +134 -0
  3. package/dist/commonjs/app/extend/application.d.ts +33 -0
  4. package/dist/commonjs/app/extend/application.js +55 -0
  5. package/dist/commonjs/app/middleware/session.d.ts +2 -0
  6. package/dist/commonjs/app/middleware/session.js +5 -0
  7. package/dist/commonjs/app.d.ts +6 -0
  8. package/dist/commonjs/app.js +29 -0
  9. package/dist/commonjs/config/config.default.d.ts +206 -0
  10. package/dist/commonjs/config/config.default.js +20 -0
  11. package/dist/commonjs/index.d.ts +2 -0
  12. package/dist/commonjs/index.js +19 -0
  13. package/dist/commonjs/package.json +3 -0
  14. package/dist/commonjs/types.d.ts +6 -0
  15. package/dist/commonjs/types.js +3 -0
  16. package/dist/esm/app/extend/application.d.ts +33 -0
  17. package/dist/esm/app/extend/application.js +49 -0
  18. package/dist/esm/app/middleware/session.d.ts +2 -0
  19. package/dist/esm/app/middleware/session.js +3 -0
  20. package/dist/esm/app.d.ts +6 -0
  21. package/dist/esm/app.js +26 -0
  22. package/dist/esm/config/config.default.d.ts +206 -0
  23. package/dist/esm/config/config.default.js +14 -0
  24. package/dist/esm/index.d.ts +2 -0
  25. package/dist/esm/index.js +3 -0
  26. package/dist/esm/package.json +3 -0
  27. package/dist/esm/types.d.ts +6 -0
  28. package/dist/esm/types.js +2 -0
  29. package/dist/package.json +4 -0
  30. package/package.json +92 -0
  31. package/src/app/extend/application.ts +59 -0
  32. package/src/app/middleware/session.ts +3 -0
  33. package/src/app.ts +30 -0
  34. package/src/config/config.default.ts +17 -0
  35. package/src/index.ts +3 -0
  36. package/src/types.ts +8 -0
  37. package/src/typings/index.d.ts +4 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) Alibaba Group Holding Limited and other contributors.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,134 @@
1
+ # @eggjs/session
2
+
3
+ [![NPM version][npm-image]][npm-url]
4
+ [![Node.js CI](https://github.com/eggjs/session/actions/workflows/nodejs.yml/badge.svg)](https://github.com/eggjs/session/actions/workflows/nodejs.yml)
5
+ [![Test coverage][codecov-image]][codecov-url]
6
+ [![Known Vulnerabilities][snyk-image]][snyk-url]
7
+ [![npm download][download-image]][download-url]
8
+ [![Node.js Version](https://img.shields.io/node/v/@eggjs/session.svg?style=flat)](https://nodejs.org/en/download/)
9
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](https://makeapullrequest.com)
10
+ ![CodeRabbit Pull Request Reviews](https://img.shields.io/coderabbit/prs/github/eggjs/session)
11
+
12
+ [npm-image]: https://img.shields.io/npm/v/@eggjs/session.svg?style=flat-square
13
+ [npm-url]: https://npmjs.org/package/@eggjs/session
14
+ [codecov-image]: https://codecov.io/gh/eggjs/session/branch/master/graph/badge.svg
15
+ [codecov-url]: https://codecov.io/gh/eggjs/session
16
+ [snyk-image]: https://snyk.io/test/npm/@eggjs/session/badge.svg?style=flat-square
17
+ [snyk-url]: https://snyk.io/test/npm/@eggjs/session
18
+ [download-image]: https://img.shields.io/npm/dm/@eggjs/session.svg?style=flat-square
19
+ [download-url]: https://npmjs.org/package/@eggjs/session
20
+
21
+ Session plugin for egg, based on [koa-session](https://github.com/koajs/session).
22
+
23
+ ## Install
24
+
25
+ ```bash
26
+ npm i @eggjs/session
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ egg-session is a built-in plugin in egg and enabled by default.
32
+
33
+ ```js
34
+ // {app_root}/config/plugin.js
35
+ exports.session = true; // enable by default
36
+ ```
37
+
38
+ ### External Store
39
+
40
+ egg-session support external store, you can store your sessions in redis, memcached or other databases.
41
+
42
+ For example, if you want to store session in redis, you must:
43
+
44
+ 1. Dependent [egg-redis](https://github.com/eggjs/egg-redis)
45
+
46
+ ```bash
47
+ npm i --save egg-redis
48
+ ```
49
+
50
+ 2. Import egg-redis as a plugin and set the configuration
51
+
52
+ ```js
53
+ // config/plugin.js
54
+ exports.redis = {
55
+ enable: true,
56
+ package: 'egg-redis',
57
+ };
58
+ ```
59
+
60
+ ```js
61
+ // config/config.default.js
62
+ exports.redis = {
63
+ // your redis configurations
64
+ };
65
+ ```
66
+
67
+ 3. Implement a session store with redis
68
+
69
+ ```js
70
+ // app.js
71
+
72
+ module.exports = app => {
73
+ // set redis session store
74
+ // session store must have 3 methods
75
+ // define sessionStore in `app.js` so you can access `app.redis`
76
+ app.sessionStore = {
77
+ async get(key) {
78
+ const res = await app.redis.get(key);
79
+ if (!res) return null;
80
+ return JSON.parse(res);
81
+ },
82
+
83
+ async set(key, value, maxAge) {
84
+ // maxAge not present means session cookies
85
+ // we can't exactly know the maxAge and just set an appropriate value like one day
86
+ if (!maxAge) maxAge = 24 * 60 * 60 * 1000;
87
+ value = JSON.stringify(value);
88
+ await app.redis.set(key, value, 'PX', maxAge);
89
+ },
90
+
91
+ async destroy(key) {
92
+ await app.redis.del(key);
93
+ },
94
+ };
95
+
96
+ // session store can be a session store class
97
+ // app.sessionStore = class Store {
98
+ // constructor(app) {
99
+ // this.app = app;
100
+ // }
101
+ // async get() {}
102
+ // async set() {}
103
+ // async destroy() {}
104
+ // };
105
+ };
106
+ ```
107
+
108
+ Once you use external session store, session is strong dependent on your external store, you can't access session if your external store is down. **Use external session stores only if necessary, avoid use session as a cache, keep session lean and stored by cookie!**
109
+
110
+ ## Configuration
111
+
112
+ Support all configurations in [koa-session](https://github.com/koajs/session).
113
+
114
+ * logValue
115
+
116
+ ```bash
117
+ Support not to print the session value when session event trigger log. Default to be true.
118
+ ```
119
+
120
+ [View the default configurations](https://github.com/eggjs/egg-session/blob/master/config/config.default.js)
121
+
122
+ ## Questions & Suggestions
123
+
124
+ Please open an issue [here](https://github.com/eggjs/egg/issues).
125
+
126
+ ## License
127
+
128
+ [MIT](LICENSE)
129
+
130
+ ## Contributors
131
+
132
+ [![Contributors](https://contrib.rocks/image?repo=eggjs/session)](https://github.com/eggjs/session/graphs/contributors)
133
+
134
+ Made with [contributors-img](https://contrib.rocks).
@@ -0,0 +1,33 @@
1
+ import { EggCore } from '@eggjs/core';
2
+ import type { SessionConfig } from '../../config/config.default.js';
3
+ export type SessionStore = Required<SessionConfig>['store'];
4
+ export type SessionStoreOrAppSessionStoreClass = SessionStore | {
5
+ new (app: Application): SessionStore;
6
+ };
7
+ export default class Application extends EggCore {
8
+ /**
9
+ * set session external store
10
+ *
11
+ * ```js
12
+ * app.sessionStore = {
13
+ * get(key): Promise<unknown>,
14
+ * set(key, data): Promise<void>,
15
+ * destroy(key): Promise<void>,
16
+ * };
17
+ *
18
+ * app.sessionStore = class SessionStore {
19
+ * constructor(app) {
20
+ * }
21
+ * get(key): Promise<unknown>,
22
+ * set(key, data): Promise<void>,
23
+ * destroy(key): Promise<void>,
24
+ * }
25
+ * ```
26
+ * @param {Class|Object} store session store class or instance
27
+ */
28
+ set sessionStore(store: SessionStoreOrAppSessionStoreClass | null | undefined);
29
+ /**
30
+ * get sessionStore instance
31
+ */
32
+ get sessionStore(): SessionStore | undefined;
33
+ }
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_assert_1 = __importDefault(require("node:assert"));
7
+ const core_1 = require("@eggjs/core");
8
+ class Application extends core_1.EggCore {
9
+ /**
10
+ * set session external store
11
+ *
12
+ * ```js
13
+ * app.sessionStore = {
14
+ * get(key): Promise<unknown>,
15
+ * set(key, data): Promise<void>,
16
+ * destroy(key): Promise<void>,
17
+ * };
18
+ *
19
+ * app.sessionStore = class SessionStore {
20
+ * constructor(app) {
21
+ * }
22
+ * get(key): Promise<unknown>,
23
+ * set(key, data): Promise<void>,
24
+ * destroy(key): Promise<void>,
25
+ * }
26
+ * ```
27
+ * @param {Class|Object} store session store class or instance
28
+ */
29
+ set sessionStore(store) {
30
+ if (this.config.session.store && this.config.env !== 'unittest') {
31
+ this.coreLogger.warn('[@eggjs/session] sessionStore already exists and will be overwrite');
32
+ }
33
+ // support this.sessionStore = null to disable external store
34
+ if (!store) {
35
+ this.config.session.store = undefined;
36
+ this.coreLogger.info('[@eggjs/session] sessionStore is disabled');
37
+ return;
38
+ }
39
+ if (typeof store === 'function') {
40
+ store = new store(this);
41
+ }
42
+ (0, node_assert_1.default)(typeof store.get === 'function', 'store.get must be function');
43
+ (0, node_assert_1.default)(typeof store.set === 'function', 'store.set must be function');
44
+ (0, node_assert_1.default)(typeof store.destroy === 'function', 'store.destroy must be function');
45
+ this.config.session.store = store;
46
+ }
47
+ /**
48
+ * get sessionStore instance
49
+ */
50
+ get sessionStore() {
51
+ return this.config.session.store;
52
+ }
53
+ }
54
+ exports.default = Application;
55
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL2V4dGVuZC9hcHBsaWNhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLDhEQUFpQztBQUNqQyxzQ0FBc0M7QUFTdEMsTUFBcUIsV0FBWSxTQUFRLGNBQU87SUFDOUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FtQkc7SUFDSCxJQUFJLFlBQVksQ0FBQyxLQUE0RDtRQUMzRSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNoRSxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxvRUFBb0UsQ0FBQyxDQUFDO1FBQzdGLENBQUM7UUFFRCw2REFBNkQ7UUFDN0QsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxHQUFHLFNBQVMsQ0FBQztZQUN0QyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQywyQ0FBMkMsQ0FBQyxDQUFDO1lBQ2xFLE9BQU87UUFDVCxDQUFDO1FBRUQsSUFBSSxPQUFPLEtBQUssS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNoQyxLQUFLLEdBQUcsSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUIsQ0FBQztRQUNELElBQUEscUJBQU0sRUFBQyxPQUFPLEtBQUssQ0FBQyxHQUFHLEtBQUssVUFBVSxFQUFFLDRCQUE0QixDQUFDLENBQUM7UUFDdEUsSUFBQSxxQkFBTSxFQUFDLE9BQU8sS0FBSyxDQUFDLEdBQUcsS0FBSyxVQUFVLEVBQUUsNEJBQTRCLENBQUMsQ0FBQztRQUN0RSxJQUFBLHFCQUFNLEVBQUMsT0FBTyxLQUFLLENBQUMsT0FBTyxLQUFLLFVBQVUsRUFBRSxnQ0FBZ0MsQ0FBQyxDQUFDO1FBQzlFLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7SUFDcEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7SUFDbkMsQ0FBQztDQUNGO0FBaERELDhCQWdEQyJ9
@@ -0,0 +1,2 @@
1
+ import { createSession } from 'koa-session';
2
+ export default createSession;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const koa_session_1 = require("koa-session");
4
+ exports.default = koa_session_1.createSession;
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvbWlkZGxld2FyZS9zZXNzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsNkNBQTRDO0FBRTVDLGtCQUFlLDJCQUFhLENBQUMifQ==
@@ -0,0 +1,6 @@
1
+ import type { ILifecycleBoot, EggCore } from '@eggjs/core';
2
+ export default class AppBoot implements ILifecycleBoot {
3
+ private readonly app;
4
+ constructor(app: EggCore);
5
+ configWillLoad(): void;
6
+ }
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_default_js_1 = require("./config/config.default.js");
4
+ class AppBoot {
5
+ app;
6
+ constructor(app) {
7
+ this.app = app;
8
+ }
9
+ configWillLoad() {
10
+ const app = this.app;
11
+ config_default_js_1.SessionConfig.parse(app.config.session);
12
+ if (!app.config.session.httpOnly) {
13
+ app.coreLogger.warn('[@eggjs/session]: please set `config.session.httpOnly` to true. It is very dangerous if session can read by client JavaScript.');
14
+ }
15
+ app.config.coreMiddleware.push('session');
16
+ // listen on session's events
17
+ app.on('session:missed', ({ ctx, key }) => {
18
+ ctx.coreLogger.warn('[session][missed] key(%s)', key);
19
+ });
20
+ app.on('session:expired', ({ ctx, key, value }) => {
21
+ ctx.coreLogger.warn('[session][expired] key(%s) value(%j)', key, app.config.session.logValue ? value : '');
22
+ });
23
+ app.on('session:invalid', ({ ctx, key, value }) => {
24
+ ctx.coreLogger.warn('[session][invalid] key(%s) value(%j)', key, app.config.session.logValue ? value : '');
25
+ });
26
+ }
27
+ }
28
+ exports.default = AppBoot;
29
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUNBLGtFQUEyRDtBQUUzRCxNQUFxQixPQUFPO0lBQ1QsR0FBRyxDQUFDO0lBRXJCLFlBQVksR0FBWTtRQUN0QixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztJQUNqQixDQUFDO0lBRUQsY0FBYztRQUNaLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDckIsaUNBQWEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUV4QyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDakMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZ0lBQWdJLENBQUMsQ0FBQztRQUN4SixDQUFDO1FBQ0QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzFDLDZCQUE2QjtRQUM3QixHQUFHLENBQUMsRUFBRSxDQUFDLGdCQUFnQixFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRTtZQUN4QyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQywyQkFBMkIsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUN4RCxDQUFDLENBQUMsQ0FBQztRQUNILEdBQUcsQ0FBQyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNoRCxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzdHLENBQUMsQ0FBQyxDQUFDO1FBQ0gsR0FBRyxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ2hELEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0csQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0Y7QUExQkQsMEJBMEJDIn0=
@@ -0,0 +1,206 @@
1
+ import z from 'zod';
2
+ export declare const SessionConfig: z.ZodObject<z.objectUtil.extendShape<{
3
+ key: z.ZodDefault<z.ZodString>;
4
+ maxAge: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"session">]>>;
5
+ autoCommit: z.ZodDefault<z.ZodBoolean>;
6
+ overwrite: z.ZodDefault<z.ZodBoolean>;
7
+ httpOnly: z.ZodDefault<z.ZodBoolean>;
8
+ signed: z.ZodDefault<z.ZodBoolean>;
9
+ rolling: z.ZodDefault<z.ZodBoolean>;
10
+ renew: z.ZodDefault<z.ZodBoolean>;
11
+ secure: z.ZodOptional<z.ZodBoolean>;
12
+ sameSite: z.ZodOptional<z.ZodString>;
13
+ externalKey: z.ZodOptional<z.ZodObject<{
14
+ get: z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodString>;
15
+ set: z.ZodFunction<z.ZodTuple<[z.ZodAny, z.ZodString], z.ZodUnknown>, z.ZodVoid>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ set: (args_0: any, args_1: string, ...args: unknown[]) => void;
18
+ get: (args_0: any, ...args: unknown[]) => string;
19
+ }, {
20
+ set: (args_0: any, args_1: string, ...args: unknown[]) => void;
21
+ get: (args_0: any, ...args: unknown[]) => string;
22
+ }>>;
23
+ store: z.ZodOptional<z.ZodObject<{
24
+ get: z.ZodFunction<z.ZodTuple<[z.ZodString, z.ZodNumber, z.ZodObject<{
25
+ rolling: z.ZodBoolean;
26
+ ctx: z.ZodAny;
27
+ }, "strip", z.ZodTypeAny, {
28
+ rolling: boolean;
29
+ ctx?: any;
30
+ }, {
31
+ rolling: boolean;
32
+ ctx?: any;
33
+ }>], z.ZodUnknown>, z.ZodPromise<z.ZodAny>>;
34
+ set: z.ZodFunction<z.ZodTuple<[z.ZodString, z.ZodAny, z.ZodNumber, z.ZodObject<{
35
+ rolling: z.ZodBoolean;
36
+ changed: z.ZodBoolean;
37
+ ctx: z.ZodAny;
38
+ }, "strip", z.ZodTypeAny, {
39
+ rolling: boolean;
40
+ changed: boolean;
41
+ ctx?: any;
42
+ }, {
43
+ rolling: boolean;
44
+ changed: boolean;
45
+ ctx?: any;
46
+ }>], z.ZodUnknown>, z.ZodPromise<z.ZodVoid>>;
47
+ destroy: z.ZodFunction<z.ZodTuple<[z.ZodString, z.ZodObject<{
48
+ ctx: z.ZodAny;
49
+ }, "strip", z.ZodTypeAny, {
50
+ ctx?: any;
51
+ }, {
52
+ ctx?: any;
53
+ }>], z.ZodUnknown>, z.ZodPromise<z.ZodVoid>>;
54
+ }, "strip", z.ZodTypeAny, {
55
+ set: (args_0: string, args_1: any, args_2: number, args_3: {
56
+ rolling: boolean;
57
+ changed: boolean;
58
+ ctx?: any;
59
+ }, ...args: unknown[]) => Promise<void>;
60
+ get: (args_0: string, args_1: number, args_2: {
61
+ rolling: boolean;
62
+ ctx?: any;
63
+ }, ...args: unknown[]) => Promise<any>;
64
+ destroy: (args_0: string, args_1: {
65
+ ctx?: any;
66
+ }, ...args: unknown[]) => Promise<void>;
67
+ }, {
68
+ set: (args_0: string, args_1: any, args_2: number, args_3: {
69
+ rolling: boolean;
70
+ changed: boolean;
71
+ ctx?: any;
72
+ }, ...args: unknown[]) => Promise<void>;
73
+ get: (args_0: string, args_1: number, args_2: {
74
+ rolling: boolean;
75
+ ctx?: any;
76
+ }, ...args: unknown[]) => Promise<any>;
77
+ destroy: (args_0: string, args_1: {
78
+ ctx?: any;
79
+ }, ...args: unknown[]) => Promise<void>;
80
+ }>>;
81
+ ContextStore: z.ZodOptional<z.ZodAny>;
82
+ encode: z.ZodDefault<z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodString>>>;
83
+ decode: z.ZodDefault<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, z.ZodAny>>;
84
+ genid: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodString>>;
85
+ prefix: z.ZodOptional<z.ZodString>;
86
+ valid: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny, z.ZodAny], z.ZodUnknown>, z.ZodAny>>;
87
+ beforeSave: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny, z.ZodAny], z.ZodUnknown>, z.ZodVoid>>;
88
+ }, {
89
+ logValue: z.ZodDefault<z.ZodBoolean>;
90
+ }>, "strip", z.ZodTypeAny, {
91
+ logValue: boolean;
92
+ key: string;
93
+ autoCommit: boolean;
94
+ overwrite: boolean;
95
+ httpOnly: boolean;
96
+ signed: boolean;
97
+ rolling: boolean;
98
+ renew: boolean;
99
+ encode: (args_0: any, ...args: unknown[]) => string;
100
+ decode: (args_0: string, ...args: unknown[]) => any;
101
+ maxAge?: number | "session" | undefined;
102
+ secure?: boolean | undefined;
103
+ sameSite?: string | undefined;
104
+ externalKey?: {
105
+ set: (args_0: any, args_1: string, ...args: unknown[]) => void;
106
+ get: (args_0: any, ...args: unknown[]) => string;
107
+ } | undefined;
108
+ store?: {
109
+ set: (args_0: string, args_1: any, args_2: number, args_3: {
110
+ rolling: boolean;
111
+ changed: boolean;
112
+ ctx?: any;
113
+ }, ...args: unknown[]) => Promise<void>;
114
+ get: (args_0: string, args_1: number, args_2: {
115
+ rolling: boolean;
116
+ ctx?: any;
117
+ }, ...args: unknown[]) => Promise<any>;
118
+ destroy: (args_0: string, args_1: {
119
+ ctx?: any;
120
+ }, ...args: unknown[]) => Promise<void>;
121
+ } | undefined;
122
+ ContextStore?: any;
123
+ genid?: ((args_0: any, ...args: unknown[]) => string) | undefined;
124
+ prefix?: string | undefined;
125
+ valid?: ((args_0: any, args_1: any, ...args: unknown[]) => any) | undefined;
126
+ beforeSave?: ((args_0: any, args_1: any, ...args: unknown[]) => void) | undefined;
127
+ }, {
128
+ logValue?: boolean | undefined;
129
+ key?: string | undefined;
130
+ maxAge?: number | "session" | undefined;
131
+ autoCommit?: boolean | undefined;
132
+ overwrite?: boolean | undefined;
133
+ httpOnly?: boolean | undefined;
134
+ signed?: boolean | undefined;
135
+ rolling?: boolean | undefined;
136
+ renew?: boolean | undefined;
137
+ secure?: boolean | undefined;
138
+ sameSite?: string | undefined;
139
+ externalKey?: {
140
+ set: (args_0: any, args_1: string, ...args: unknown[]) => void;
141
+ get: (args_0: any, ...args: unknown[]) => string;
142
+ } | undefined;
143
+ store?: {
144
+ set: (args_0: string, args_1: any, args_2: number, args_3: {
145
+ rolling: boolean;
146
+ changed: boolean;
147
+ ctx?: any;
148
+ }, ...args: unknown[]) => Promise<void>;
149
+ get: (args_0: string, args_1: number, args_2: {
150
+ rolling: boolean;
151
+ ctx?: any;
152
+ }, ...args: unknown[]) => Promise<any>;
153
+ destroy: (args_0: string, args_1: {
154
+ ctx?: any;
155
+ }, ...args: unknown[]) => Promise<void>;
156
+ } | undefined;
157
+ ContextStore?: any;
158
+ encode?: ((args_0: any, ...args: unknown[]) => string) | undefined;
159
+ decode?: ((args_0: string, ...args: unknown[]) => any) | undefined;
160
+ genid?: ((args_0: any, ...args: unknown[]) => string) | undefined;
161
+ prefix?: string | undefined;
162
+ valid?: ((args_0: any, args_1: any, ...args: unknown[]) => any) | undefined;
163
+ beforeSave?: ((args_0: any, args_1: any, ...args: unknown[]) => void) | undefined;
164
+ }>;
165
+ export type SessionConfig = z.infer<typeof SessionConfig>;
166
+ declare const _default: {
167
+ session: {
168
+ logValue: boolean;
169
+ key: string;
170
+ autoCommit: boolean;
171
+ overwrite: boolean;
172
+ httpOnly: boolean;
173
+ signed: boolean;
174
+ rolling: boolean;
175
+ renew: boolean;
176
+ encode: (args_0: any, ...args: unknown[]) => string;
177
+ decode: (args_0: string, ...args: unknown[]) => any;
178
+ maxAge?: number | "session" | undefined;
179
+ secure?: boolean | undefined;
180
+ sameSite?: string | undefined;
181
+ externalKey?: {
182
+ set: (args_0: any, args_1: string, ...args: unknown[]) => void;
183
+ get: (args_0: any, ...args: unknown[]) => string;
184
+ } | undefined;
185
+ store?: {
186
+ set: (args_0: string, args_1: any, args_2: number, args_3: {
187
+ rolling: boolean;
188
+ changed: boolean;
189
+ ctx?: any;
190
+ }, ...args: unknown[]) => Promise<void>;
191
+ get: (args_0: string, args_1: number, args_2: {
192
+ rolling: boolean;
193
+ ctx?: any;
194
+ }, ...args: unknown[]) => Promise<any>;
195
+ destroy: (args_0: string, args_1: {
196
+ ctx?: any;
197
+ }, ...args: unknown[]) => Promise<void>;
198
+ } | undefined;
199
+ ContextStore?: any;
200
+ genid?: ((args_0: any, ...args: unknown[]) => string) | undefined;
201
+ prefix?: string | undefined;
202
+ valid?: ((args_0: any, args_1: any, ...args: unknown[]) => any) | undefined;
203
+ beforeSave?: ((args_0: any, args_1: any, ...args: unknown[]) => void) | undefined;
204
+ };
205
+ };
206
+ export default _default;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SessionConfig = void 0;
7
+ const zod_1 = __importDefault(require("zod"));
8
+ const koa_session_1 = require("koa-session");
9
+ exports.SessionConfig = koa_session_1.SessionOptions.extend({
10
+ logValue: zod_1.default.boolean().default(true),
11
+ });
12
+ exports.default = {
13
+ session: exports.SessionConfig.parse({
14
+ maxAge: 24 * 3600 * 1000, // ms, one day
15
+ key: 'EGG_SESS',
16
+ httpOnly: true,
17
+ encrypt: true,
18
+ }),
19
+ };
20
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmRlZmF1bHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29uZmlnL2NvbmZpZy5kZWZhdWx0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLDhDQUFvQjtBQUNwQiw2Q0FBNkM7QUFFaEMsUUFBQSxhQUFhLEdBQUcsNEJBQWMsQ0FBQyxNQUFNLENBQUM7SUFDakQsUUFBUSxFQUFFLGFBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO0NBQ3BDLENBQUMsQ0FBQztBQUlILGtCQUFlO0lBQ2IsT0FBTyxFQUFFLHFCQUFhLENBQUMsS0FBSyxDQUFDO1FBQzNCLE1BQU0sRUFBRSxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksRUFBRSxjQUFjO1FBQ3hDLEdBQUcsRUFBRSxVQUFVO1FBQ2YsUUFBUSxFQUFFLElBQUk7UUFDZCxPQUFPLEVBQUUsSUFBSTtLQUNkLENBQUM7Q0FDSCxDQUFDIn0=
@@ -0,0 +1,2 @@
1
+ import './types.js';
2
+ export * from './config/config.default.js';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ require("./types.js");
18
+ __exportStar(require("./config/config.default.js"), exports);
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHNCQUFvQjtBQUVwQiw2REFBMkMifQ==
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,6 @@
1
+ import type { SessionConfig } from './config/config.default.js';
2
+ declare module '@eggjs/core' {
3
+ interface EggAppConfig {
4
+ session: SessionConfig;
5
+ }
6
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,33 @@
1
+ import { EggCore } from '@eggjs/core';
2
+ import type { SessionConfig } from '../../config/config.default.js';
3
+ export type SessionStore = Required<SessionConfig>['store'];
4
+ export type SessionStoreOrAppSessionStoreClass = SessionStore | {
5
+ new (app: Application): SessionStore;
6
+ };
7
+ export default class Application extends EggCore {
8
+ /**
9
+ * set session external store
10
+ *
11
+ * ```js
12
+ * app.sessionStore = {
13
+ * get(key): Promise<unknown>,
14
+ * set(key, data): Promise<void>,
15
+ * destroy(key): Promise<void>,
16
+ * };
17
+ *
18
+ * app.sessionStore = class SessionStore {
19
+ * constructor(app) {
20
+ * }
21
+ * get(key): Promise<unknown>,
22
+ * set(key, data): Promise<void>,
23
+ * destroy(key): Promise<void>,
24
+ * }
25
+ * ```
26
+ * @param {Class|Object} store session store class or instance
27
+ */
28
+ set sessionStore(store: SessionStoreOrAppSessionStoreClass | null | undefined);
29
+ /**
30
+ * get sessionStore instance
31
+ */
32
+ get sessionStore(): SessionStore | undefined;
33
+ }
@@ -0,0 +1,49 @@
1
+ import assert from 'node:assert';
2
+ import { EggCore } from '@eggjs/core';
3
+ export default class Application extends EggCore {
4
+ /**
5
+ * set session external store
6
+ *
7
+ * ```js
8
+ * app.sessionStore = {
9
+ * get(key): Promise<unknown>,
10
+ * set(key, data): Promise<void>,
11
+ * destroy(key): Promise<void>,
12
+ * };
13
+ *
14
+ * app.sessionStore = class SessionStore {
15
+ * constructor(app) {
16
+ * }
17
+ * get(key): Promise<unknown>,
18
+ * set(key, data): Promise<void>,
19
+ * destroy(key): Promise<void>,
20
+ * }
21
+ * ```
22
+ * @param {Class|Object} store session store class or instance
23
+ */
24
+ set sessionStore(store) {
25
+ if (this.config.session.store && this.config.env !== 'unittest') {
26
+ this.coreLogger.warn('[@eggjs/session] sessionStore already exists and will be overwrite');
27
+ }
28
+ // support this.sessionStore = null to disable external store
29
+ if (!store) {
30
+ this.config.session.store = undefined;
31
+ this.coreLogger.info('[@eggjs/session] sessionStore is disabled');
32
+ return;
33
+ }
34
+ if (typeof store === 'function') {
35
+ store = new store(this);
36
+ }
37
+ assert(typeof store.get === 'function', 'store.get must be function');
38
+ assert(typeof store.set === 'function', 'store.set must be function');
39
+ assert(typeof store.destroy === 'function', 'store.destroy must be function');
40
+ this.config.session.store = store;
41
+ }
42
+ /**
43
+ * get sessionStore instance
44
+ */
45
+ get sessionStore() {
46
+ return this.config.session.store;
47
+ }
48
+ }
49
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwbGljYXRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL2V4dGVuZC9hcHBsaWNhdGlvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDakMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQVN0QyxNQUFNLENBQUMsT0FBTyxPQUFPLFdBQVksU0FBUSxPQUFPO0lBQzlDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O09BbUJHO0lBQ0gsSUFBSSxZQUFZLENBQUMsS0FBNEQ7UUFDM0UsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDaEUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsb0VBQW9FLENBQUMsQ0FBQztRQUM3RixDQUFDO1FBRUQsNkRBQTZEO1FBQzdELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNYLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxTQUFTLENBQUM7WUFDdEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsMkNBQTJDLENBQUMsQ0FBQztZQUNsRSxPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksT0FBTyxLQUFLLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDaEMsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFCLENBQUM7UUFDRCxNQUFNLENBQUMsT0FBTyxLQUFLLENBQUMsR0FBRyxLQUFLLFVBQVUsRUFBRSw0QkFBNEIsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sQ0FBQyxPQUFPLEtBQUssQ0FBQyxHQUFHLEtBQUssVUFBVSxFQUFFLDRCQUE0QixDQUFDLENBQUM7UUFDdEUsTUFBTSxDQUFDLE9BQU8sS0FBSyxDQUFDLE9BQU8sS0FBSyxVQUFVLEVBQUUsZ0NBQWdDLENBQUMsQ0FBQztRQUM5RSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksWUFBWTtRQUNkLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO0lBQ25DLENBQUM7Q0FDRiJ9
@@ -0,0 +1,2 @@
1
+ import { createSession } from 'koa-session';
2
+ export default createSession;
@@ -0,0 +1,3 @@
1
+ import { createSession } from 'koa-session';
2
+ export default createSession;
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvbWlkZGxld2FyZS9zZXNzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFNUMsZUFBZSxhQUFhLENBQUMifQ==
@@ -0,0 +1,6 @@
1
+ import type { ILifecycleBoot, EggCore } from '@eggjs/core';
2
+ export default class AppBoot implements ILifecycleBoot {
3
+ private readonly app;
4
+ constructor(app: EggCore);
5
+ configWillLoad(): void;
6
+ }
@@ -0,0 +1,26 @@
1
+ import { SessionConfig } from './config/config.default.js';
2
+ export default class AppBoot {
3
+ app;
4
+ constructor(app) {
5
+ this.app = app;
6
+ }
7
+ configWillLoad() {
8
+ const app = this.app;
9
+ SessionConfig.parse(app.config.session);
10
+ if (!app.config.session.httpOnly) {
11
+ app.coreLogger.warn('[@eggjs/session]: please set `config.session.httpOnly` to true. It is very dangerous if session can read by client JavaScript.');
12
+ }
13
+ app.config.coreMiddleware.push('session');
14
+ // listen on session's events
15
+ app.on('session:missed', ({ ctx, key }) => {
16
+ ctx.coreLogger.warn('[session][missed] key(%s)', key);
17
+ });
18
+ app.on('session:expired', ({ ctx, key, value }) => {
19
+ ctx.coreLogger.warn('[session][expired] key(%s) value(%j)', key, app.config.session.logValue ? value : '');
20
+ });
21
+ app.on('session:invalid', ({ ctx, key, value }) => {
22
+ ctx.coreLogger.warn('[session][invalid] key(%s) value(%j)', key, app.config.session.logValue ? value : '');
23
+ });
24
+ }
25
+ }
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFM0QsTUFBTSxDQUFDLE9BQU8sT0FBTyxPQUFPO0lBQ1QsR0FBRyxDQUFDO0lBRXJCLFlBQVksR0FBWTtRQUN0QixJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztJQUNqQixDQUFDO0lBRUQsY0FBYztRQUNaLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDckIsYUFBYSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXhDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNqQyxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxnSUFBZ0ksQ0FBQyxDQUFDO1FBQ3hKLENBQUM7UUFDRCxHQUFHLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDMUMsNkJBQTZCO1FBQzdCLEdBQUcsQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFO1lBQ3hDLEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLDJCQUEyQixFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3hELENBQUMsQ0FBQyxDQUFDO1FBQ0gsR0FBRyxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFO1lBQ2hELEdBQUcsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDN0csQ0FBQyxDQUFDLENBQUM7UUFDSCxHQUFHLENBQUMsRUFBRSxDQUFDLGlCQUFpQixFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDaEQsR0FBRyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsc0NBQXNDLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUM3RyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRiJ9
@@ -0,0 +1,206 @@
1
+ import z from 'zod';
2
+ export declare const SessionConfig: z.ZodObject<z.objectUtil.extendShape<{
3
+ key: z.ZodDefault<z.ZodString>;
4
+ maxAge: z.ZodOptional<z.ZodUnion<[z.ZodNumber, z.ZodLiteral<"session">]>>;
5
+ autoCommit: z.ZodDefault<z.ZodBoolean>;
6
+ overwrite: z.ZodDefault<z.ZodBoolean>;
7
+ httpOnly: z.ZodDefault<z.ZodBoolean>;
8
+ signed: z.ZodDefault<z.ZodBoolean>;
9
+ rolling: z.ZodDefault<z.ZodBoolean>;
10
+ renew: z.ZodDefault<z.ZodBoolean>;
11
+ secure: z.ZodOptional<z.ZodBoolean>;
12
+ sameSite: z.ZodOptional<z.ZodString>;
13
+ externalKey: z.ZodOptional<z.ZodObject<{
14
+ get: z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodString>;
15
+ set: z.ZodFunction<z.ZodTuple<[z.ZodAny, z.ZodString], z.ZodUnknown>, z.ZodVoid>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ set: (args_0: any, args_1: string, ...args: unknown[]) => void;
18
+ get: (args_0: any, ...args: unknown[]) => string;
19
+ }, {
20
+ set: (args_0: any, args_1: string, ...args: unknown[]) => void;
21
+ get: (args_0: any, ...args: unknown[]) => string;
22
+ }>>;
23
+ store: z.ZodOptional<z.ZodObject<{
24
+ get: z.ZodFunction<z.ZodTuple<[z.ZodString, z.ZodNumber, z.ZodObject<{
25
+ rolling: z.ZodBoolean;
26
+ ctx: z.ZodAny;
27
+ }, "strip", z.ZodTypeAny, {
28
+ rolling: boolean;
29
+ ctx?: any;
30
+ }, {
31
+ rolling: boolean;
32
+ ctx?: any;
33
+ }>], z.ZodUnknown>, z.ZodPromise<z.ZodAny>>;
34
+ set: z.ZodFunction<z.ZodTuple<[z.ZodString, z.ZodAny, z.ZodNumber, z.ZodObject<{
35
+ rolling: z.ZodBoolean;
36
+ changed: z.ZodBoolean;
37
+ ctx: z.ZodAny;
38
+ }, "strip", z.ZodTypeAny, {
39
+ rolling: boolean;
40
+ changed: boolean;
41
+ ctx?: any;
42
+ }, {
43
+ rolling: boolean;
44
+ changed: boolean;
45
+ ctx?: any;
46
+ }>], z.ZodUnknown>, z.ZodPromise<z.ZodVoid>>;
47
+ destroy: z.ZodFunction<z.ZodTuple<[z.ZodString, z.ZodObject<{
48
+ ctx: z.ZodAny;
49
+ }, "strip", z.ZodTypeAny, {
50
+ ctx?: any;
51
+ }, {
52
+ ctx?: any;
53
+ }>], z.ZodUnknown>, z.ZodPromise<z.ZodVoid>>;
54
+ }, "strip", z.ZodTypeAny, {
55
+ set: (args_0: string, args_1: any, args_2: number, args_3: {
56
+ rolling: boolean;
57
+ changed: boolean;
58
+ ctx?: any;
59
+ }, ...args: unknown[]) => Promise<void>;
60
+ get: (args_0: string, args_1: number, args_2: {
61
+ rolling: boolean;
62
+ ctx?: any;
63
+ }, ...args: unknown[]) => Promise<any>;
64
+ destroy: (args_0: string, args_1: {
65
+ ctx?: any;
66
+ }, ...args: unknown[]) => Promise<void>;
67
+ }, {
68
+ set: (args_0: string, args_1: any, args_2: number, args_3: {
69
+ rolling: boolean;
70
+ changed: boolean;
71
+ ctx?: any;
72
+ }, ...args: unknown[]) => Promise<void>;
73
+ get: (args_0: string, args_1: number, args_2: {
74
+ rolling: boolean;
75
+ ctx?: any;
76
+ }, ...args: unknown[]) => Promise<any>;
77
+ destroy: (args_0: string, args_1: {
78
+ ctx?: any;
79
+ }, ...args: unknown[]) => Promise<void>;
80
+ }>>;
81
+ ContextStore: z.ZodOptional<z.ZodAny>;
82
+ encode: z.ZodDefault<z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodString>>>;
83
+ decode: z.ZodDefault<z.ZodFunction<z.ZodTuple<[z.ZodString], z.ZodUnknown>, z.ZodAny>>;
84
+ genid: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny], z.ZodUnknown>, z.ZodString>>;
85
+ prefix: z.ZodOptional<z.ZodString>;
86
+ valid: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny, z.ZodAny], z.ZodUnknown>, z.ZodAny>>;
87
+ beforeSave: z.ZodOptional<z.ZodFunction<z.ZodTuple<[z.ZodAny, z.ZodAny], z.ZodUnknown>, z.ZodVoid>>;
88
+ }, {
89
+ logValue: z.ZodDefault<z.ZodBoolean>;
90
+ }>, "strip", z.ZodTypeAny, {
91
+ logValue: boolean;
92
+ key: string;
93
+ autoCommit: boolean;
94
+ overwrite: boolean;
95
+ httpOnly: boolean;
96
+ signed: boolean;
97
+ rolling: boolean;
98
+ renew: boolean;
99
+ encode: (args_0: any, ...args: unknown[]) => string;
100
+ decode: (args_0: string, ...args: unknown[]) => any;
101
+ maxAge?: number | "session" | undefined;
102
+ secure?: boolean | undefined;
103
+ sameSite?: string | undefined;
104
+ externalKey?: {
105
+ set: (args_0: any, args_1: string, ...args: unknown[]) => void;
106
+ get: (args_0: any, ...args: unknown[]) => string;
107
+ } | undefined;
108
+ store?: {
109
+ set: (args_0: string, args_1: any, args_2: number, args_3: {
110
+ rolling: boolean;
111
+ changed: boolean;
112
+ ctx?: any;
113
+ }, ...args: unknown[]) => Promise<void>;
114
+ get: (args_0: string, args_1: number, args_2: {
115
+ rolling: boolean;
116
+ ctx?: any;
117
+ }, ...args: unknown[]) => Promise<any>;
118
+ destroy: (args_0: string, args_1: {
119
+ ctx?: any;
120
+ }, ...args: unknown[]) => Promise<void>;
121
+ } | undefined;
122
+ ContextStore?: any;
123
+ genid?: ((args_0: any, ...args: unknown[]) => string) | undefined;
124
+ prefix?: string | undefined;
125
+ valid?: ((args_0: any, args_1: any, ...args: unknown[]) => any) | undefined;
126
+ beforeSave?: ((args_0: any, args_1: any, ...args: unknown[]) => void) | undefined;
127
+ }, {
128
+ logValue?: boolean | undefined;
129
+ key?: string | undefined;
130
+ maxAge?: number | "session" | undefined;
131
+ autoCommit?: boolean | undefined;
132
+ overwrite?: boolean | undefined;
133
+ httpOnly?: boolean | undefined;
134
+ signed?: boolean | undefined;
135
+ rolling?: boolean | undefined;
136
+ renew?: boolean | undefined;
137
+ secure?: boolean | undefined;
138
+ sameSite?: string | undefined;
139
+ externalKey?: {
140
+ set: (args_0: any, args_1: string, ...args: unknown[]) => void;
141
+ get: (args_0: any, ...args: unknown[]) => string;
142
+ } | undefined;
143
+ store?: {
144
+ set: (args_0: string, args_1: any, args_2: number, args_3: {
145
+ rolling: boolean;
146
+ changed: boolean;
147
+ ctx?: any;
148
+ }, ...args: unknown[]) => Promise<void>;
149
+ get: (args_0: string, args_1: number, args_2: {
150
+ rolling: boolean;
151
+ ctx?: any;
152
+ }, ...args: unknown[]) => Promise<any>;
153
+ destroy: (args_0: string, args_1: {
154
+ ctx?: any;
155
+ }, ...args: unknown[]) => Promise<void>;
156
+ } | undefined;
157
+ ContextStore?: any;
158
+ encode?: ((args_0: any, ...args: unknown[]) => string) | undefined;
159
+ decode?: ((args_0: string, ...args: unknown[]) => any) | undefined;
160
+ genid?: ((args_0: any, ...args: unknown[]) => string) | undefined;
161
+ prefix?: string | undefined;
162
+ valid?: ((args_0: any, args_1: any, ...args: unknown[]) => any) | undefined;
163
+ beforeSave?: ((args_0: any, args_1: any, ...args: unknown[]) => void) | undefined;
164
+ }>;
165
+ export type SessionConfig = z.infer<typeof SessionConfig>;
166
+ declare const _default: {
167
+ session: {
168
+ logValue: boolean;
169
+ key: string;
170
+ autoCommit: boolean;
171
+ overwrite: boolean;
172
+ httpOnly: boolean;
173
+ signed: boolean;
174
+ rolling: boolean;
175
+ renew: boolean;
176
+ encode: (args_0: any, ...args: unknown[]) => string;
177
+ decode: (args_0: string, ...args: unknown[]) => any;
178
+ maxAge?: number | "session" | undefined;
179
+ secure?: boolean | undefined;
180
+ sameSite?: string | undefined;
181
+ externalKey?: {
182
+ set: (args_0: any, args_1: string, ...args: unknown[]) => void;
183
+ get: (args_0: any, ...args: unknown[]) => string;
184
+ } | undefined;
185
+ store?: {
186
+ set: (args_0: string, args_1: any, args_2: number, args_3: {
187
+ rolling: boolean;
188
+ changed: boolean;
189
+ ctx?: any;
190
+ }, ...args: unknown[]) => Promise<void>;
191
+ get: (args_0: string, args_1: number, args_2: {
192
+ rolling: boolean;
193
+ ctx?: any;
194
+ }, ...args: unknown[]) => Promise<any>;
195
+ destroy: (args_0: string, args_1: {
196
+ ctx?: any;
197
+ }, ...args: unknown[]) => Promise<void>;
198
+ } | undefined;
199
+ ContextStore?: any;
200
+ genid?: ((args_0: any, ...args: unknown[]) => string) | undefined;
201
+ prefix?: string | undefined;
202
+ valid?: ((args_0: any, args_1: any, ...args: unknown[]) => any) | undefined;
203
+ beforeSave?: ((args_0: any, args_1: any, ...args: unknown[]) => void) | undefined;
204
+ };
205
+ };
206
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import z from 'zod';
2
+ import { SessionOptions } from 'koa-session';
3
+ export const SessionConfig = SessionOptions.extend({
4
+ logValue: z.boolean().default(true),
5
+ });
6
+ export default {
7
+ session: SessionConfig.parse({
8
+ maxAge: 24 * 3600 * 1000, // ms, one day
9
+ key: 'EGG_SESS',
10
+ httpOnly: true,
11
+ encrypt: true,
12
+ }),
13
+ };
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmRlZmF1bHQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29uZmlnL2NvbmZpZy5kZWZhdWx0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQztBQUNwQixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRTdDLE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxjQUFjLENBQUMsTUFBTSxDQUFDO0lBQ2pELFFBQVEsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztDQUNwQyxDQUFDLENBQUM7QUFJSCxlQUFlO0lBQ2IsT0FBTyxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUM7UUFDM0IsTUFBTSxFQUFFLEVBQUUsR0FBRyxJQUFJLEdBQUcsSUFBSSxFQUFFLGNBQWM7UUFDeEMsR0FBRyxFQUFFLFVBQVU7UUFDZixRQUFRLEVBQUUsSUFBSTtRQUNkLE9BQU8sRUFBRSxJQUFJO0tBQ2QsQ0FBQztDQUNILENBQUMifQ==
@@ -0,0 +1,2 @@
1
+ import './types.js';
2
+ export * from './config/config.default.js';
@@ -0,0 +1,3 @@
1
+ import './types.js';
2
+ export * from './config/config.default.js';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxZQUFZLENBQUM7QUFFcEIsY0FBYyw0QkFBNEIsQ0FBQyJ9
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,6 @@
1
+ import type { SessionConfig } from './config/config.default.js';
2
+ declare module '@eggjs/core' {
3
+ interface EggAppConfig {
4
+ session: SessionConfig;
5
+ }
6
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -0,0 +1,4 @@
1
+ {
2
+ "name": "@eggjs/session",
3
+ "version": "4.0.0"
4
+ }
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "@eggjs/session",
3
+ "version": "4.0.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "description": "session plugin for egg",
8
+ "eggPlugin": {
9
+ "name": "session",
10
+ "exports": {
11
+ "import": "./dist/esm",
12
+ "require": "./dist/commonjs",
13
+ "typescript": "./src"
14
+ }
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git@github.com:eggjs/session.git"
19
+ },
20
+ "author": "dead_horse",
21
+ "keywords": [
22
+ "egg",
23
+ "egg-plugin",
24
+ "eggPlugin",
25
+ "session",
26
+ "cookie"
27
+ ],
28
+ "engines": {
29
+ "node": ">= 18.19.0"
30
+ },
31
+ "dependencies": {
32
+ "@eggjs/core": "^6.2.13",
33
+ "koa-session": "^7.0.2",
34
+ "zod": "^3.24.1"
35
+ },
36
+ "devDependencies": {
37
+ "@arethetypeswrong/cli": "^0.17.1",
38
+ "@eggjs/bin": "7",
39
+ "@eggjs/mock": "^6.0.5",
40
+ "@eggjs/supertest": "^8.2.0",
41
+ "@eggjs/tsconfig": "1",
42
+ "@types/mocha": "10",
43
+ "@types/node": "22",
44
+ "egg": "^4.0.1",
45
+ "egg-redis": "^2.6.0",
46
+ "eslint": "8",
47
+ "eslint-config-egg": "14",
48
+ "rimraf": "6",
49
+ "snap-shot-it": "^7.9.10",
50
+ "tshy": "3",
51
+ "tshy-after": "1",
52
+ "typescript": "5"
53
+ },
54
+ "scripts": {
55
+ "lint": "eslint --cache src test --ext .ts",
56
+ "pretest": "npm run clean && npm run lint -- --fix",
57
+ "test": "egg-bin test",
58
+ "test:snapshot:update": "SNAPSHOT_UPDATE=1 egg-bin test",
59
+ "preci": "npm run clean && npm run lint",
60
+ "ci": "egg-bin cov",
61
+ "postci": "npm run prepublishOnly && npm run clean",
62
+ "clean": "rimraf dist",
63
+ "prepublishOnly": "tshy && tshy-after && attw --pack"
64
+ },
65
+ "type": "module",
66
+ "tshy": {
67
+ "exports": {
68
+ ".": "./src/index.ts",
69
+ "./package.json": "./package.json"
70
+ }
71
+ },
72
+ "exports": {
73
+ ".": {
74
+ "import": {
75
+ "types": "./dist/esm/index.d.ts",
76
+ "default": "./dist/esm/index.js"
77
+ },
78
+ "require": {
79
+ "types": "./dist/commonjs/index.d.ts",
80
+ "default": "./dist/commonjs/index.js"
81
+ }
82
+ },
83
+ "./package.json": "./package.json"
84
+ },
85
+ "files": [
86
+ "dist",
87
+ "src"
88
+ ],
89
+ "types": "./dist/commonjs/index.d.ts",
90
+ "main": "./dist/commonjs/index.js",
91
+ "module": "./dist/esm/index.js"
92
+ }
@@ -0,0 +1,59 @@
1
+ import assert from 'node:assert';
2
+ import { EggCore } from '@eggjs/core';
3
+ import type { SessionConfig } from '../../config/config.default.js';
4
+
5
+ export type SessionStore = Required<SessionConfig>['store'];
6
+
7
+ export type SessionStoreOrAppSessionStoreClass = SessionStore | {
8
+ new(app: Application): SessionStore;
9
+ };
10
+
11
+ export default class Application extends EggCore {
12
+ /**
13
+ * set session external store
14
+ *
15
+ * ```js
16
+ * app.sessionStore = {
17
+ * get(key): Promise<unknown>,
18
+ * set(key, data): Promise<void>,
19
+ * destroy(key): Promise<void>,
20
+ * };
21
+ *
22
+ * app.sessionStore = class SessionStore {
23
+ * constructor(app) {
24
+ * }
25
+ * get(key): Promise<unknown>,
26
+ * set(key, data): Promise<void>,
27
+ * destroy(key): Promise<void>,
28
+ * }
29
+ * ```
30
+ * @param {Class|Object} store session store class or instance
31
+ */
32
+ set sessionStore(store: SessionStoreOrAppSessionStoreClass | null | undefined) {
33
+ if (this.config.session.store && this.config.env !== 'unittest') {
34
+ this.coreLogger.warn('[@eggjs/session] sessionStore already exists and will be overwrite');
35
+ }
36
+
37
+ // support this.sessionStore = null to disable external store
38
+ if (!store) {
39
+ this.config.session.store = undefined;
40
+ this.coreLogger.info('[@eggjs/session] sessionStore is disabled');
41
+ return;
42
+ }
43
+
44
+ if (typeof store === 'function') {
45
+ store = new store(this);
46
+ }
47
+ assert(typeof store.get === 'function', 'store.get must be function');
48
+ assert(typeof store.set === 'function', 'store.set must be function');
49
+ assert(typeof store.destroy === 'function', 'store.destroy must be function');
50
+ this.config.session.store = store;
51
+ }
52
+
53
+ /**
54
+ * get sessionStore instance
55
+ */
56
+ get sessionStore(): SessionStore | undefined {
57
+ return this.config.session.store;
58
+ }
59
+ }
@@ -0,0 +1,3 @@
1
+ import { createSession } from 'koa-session';
2
+
3
+ export default createSession;
package/src/app.ts ADDED
@@ -0,0 +1,30 @@
1
+ import type { ILifecycleBoot, EggCore } from '@eggjs/core';
2
+ import { SessionConfig } from './config/config.default.js';
3
+
4
+ export default class AppBoot implements ILifecycleBoot {
5
+ private readonly app;
6
+
7
+ constructor(app: EggCore) {
8
+ this.app = app;
9
+ }
10
+
11
+ configWillLoad() {
12
+ const app = this.app;
13
+ SessionConfig.parse(app.config.session);
14
+
15
+ if (!app.config.session.httpOnly) {
16
+ app.coreLogger.warn('[@eggjs/session]: please set `config.session.httpOnly` to true. It is very dangerous if session can read by client JavaScript.');
17
+ }
18
+ app.config.coreMiddleware.push('session');
19
+ // listen on session's events
20
+ app.on('session:missed', ({ ctx, key }) => {
21
+ ctx.coreLogger.warn('[session][missed] key(%s)', key);
22
+ });
23
+ app.on('session:expired', ({ ctx, key, value }) => {
24
+ ctx.coreLogger.warn('[session][expired] key(%s) value(%j)', key, app.config.session.logValue ? value : '');
25
+ });
26
+ app.on('session:invalid', ({ ctx, key, value }) => {
27
+ ctx.coreLogger.warn('[session][invalid] key(%s) value(%j)', key, app.config.session.logValue ? value : '');
28
+ });
29
+ }
30
+ }
@@ -0,0 +1,17 @@
1
+ import z from 'zod';
2
+ import { SessionOptions } from 'koa-session';
3
+
4
+ export const SessionConfig = SessionOptions.extend({
5
+ logValue: z.boolean().default(true),
6
+ });
7
+
8
+ export type SessionConfig = z.infer<typeof SessionConfig>;
9
+
10
+ export default {
11
+ session: SessionConfig.parse({
12
+ maxAge: 24 * 3600 * 1000, // ms, one day
13
+ key: 'EGG_SESS',
14
+ httpOnly: true,
15
+ encrypt: true,
16
+ }),
17
+ };
package/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ import './types.js';
2
+
3
+ export * from './config/config.default.js';
package/src/types.ts ADDED
@@ -0,0 +1,8 @@
1
+ import type { SessionConfig } from './config/config.default.js';
2
+
3
+ declare module '@eggjs/core' {
4
+ // add EggAppConfig overrides types
5
+ interface EggAppConfig {
6
+ session: SessionConfig;
7
+ }
8
+ }
@@ -0,0 +1,4 @@
1
+ // make sure to import egg typings and let typescript know about it
2
+ // @see https://github.com/whxaxes/blog/issues/11
3
+ // and https://www.typescriptlang.org/docs/handbook/declaration-merging.html
4
+ import 'egg';