@nocobase/plugin-auth 1.6.0-alpha.2 → 1.6.0-alpha.21

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 (43) hide show
  1. package/dist/client/{938.index.js → 0091d4359312cb07.js} +1 -1
  2. package/dist/client/88ef1c520c08b674.js +10 -0
  3. package/dist/client/{851.index.js → 974ac9de644a1d1f.js} +1 -1
  4. package/dist/client/{280.index.js → 9e603524b127e7b4.js} +1 -1
  5. package/dist/client/index.d.ts +1 -1
  6. package/dist/client/index.js +1 -1
  7. package/dist/client/interceptors.d.ts +13 -0
  8. package/dist/client/settings/token-policy/components.d.ts +15 -0
  9. package/dist/client/settings/token-policy/hooks.d.ts +24 -0
  10. package/dist/client/settings/token-policy/index.d.ts +10 -0
  11. package/dist/constants.d.ts +12 -0
  12. package/dist/constants.js +45 -0
  13. package/dist/externalVersion.js +11 -8
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.js +4 -2
  16. package/dist/locale/en-US.json +18 -1
  17. package/dist/locale/zh-CN.json +17 -1
  18. package/dist/node_modules/cron/package.json +1 -1
  19. package/dist/node_modules/ms/index.js +1 -0
  20. package/dist/node_modules/ms/package.json +1 -0
  21. package/dist/server/actions/auth.js +6 -0
  22. package/dist/server/basic-auth.js +4 -1
  23. package/dist/server/collections/authenticators.js +1 -0
  24. package/dist/server/collections/issued-tokens.d.ts +10 -0
  25. package/dist/server/collections/issued-tokens.js +70 -0
  26. package/dist/server/collections/token-blacklist.js +1 -0
  27. package/dist/server/collections/token-poilcy-config.d.ts +10 -0
  28. package/dist/server/collections/token-poilcy-config.js +57 -0
  29. package/dist/server/collections/users-authenticators.js +1 -0
  30. package/dist/server/index.d.ts +2 -0
  31. package/dist/server/index.js +8 -2
  32. package/dist/server/migrations/20241229080941-create-token-policy-config.d.ts +14 -0
  33. package/dist/server/migrations/20241229080941-create-token-policy-config.js +58 -0
  34. package/dist/server/plugin.js +107 -54
  35. package/dist/server/storer.d.ts +8 -2
  36. package/dist/server/storer.js +28 -3
  37. package/dist/server/token-blacklist.js +13 -2
  38. package/dist/server/token-controller.d.ts +40 -0
  39. package/dist/server/token-controller.js +161 -0
  40. package/dist/types.d.ts +9 -0
  41. package/dist/types.js +24 -0
  42. package/package.json +5 -3
  43. /package/dist/client/{890.index.js → 43e9587ca4936ffe.js} +0 -0
@@ -37,11 +37,22 @@ class TokenBlacklistService {
37
37
  try {
38
38
  this.bloomFilter = await plugin.app.cacheManager.createBloomFilter();
39
39
  await this.bloomFilter.reserve(this.cacheKey, 1e-3, 1e6);
40
- const data = await this.repo.find({ fields: ["token"], raw: true });
40
+ const data = await this.repo.find({
41
+ fields: ["token"],
42
+ filter: {
43
+ expiration: {
44
+ $dateAfter: /* @__PURE__ */ new Date()
45
+ }
46
+ },
47
+ raw: true
48
+ });
41
49
  const tokens = data.map((item) => item.token);
50
+ if (!tokens.length) {
51
+ return;
52
+ }
42
53
  await this.bloomFilter.mAdd(this.cacheKey, tokens);
43
54
  } catch (error) {
44
- plugin.app.logger.error("token-blacklist: create bloom filter failed", error);
55
+ plugin.app.logger.warn("token-blacklist: create bloom filter failed", error);
45
56
  this.bloomFilter = null;
46
57
  }
47
58
  });
@@ -0,0 +1,40 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import { ITokenControlService, TokenPolicyConfig, NumericTokenPolicyConfig, TokenInfo } from '@nocobase/auth';
10
+ import type { SystemLogger } from '@nocobase/logger';
11
+ import { Cache } from '@nocobase/cache';
12
+ import Application from '@nocobase/server';
13
+ import Database from '@nocobase/database';
14
+ type TokenControlService = ITokenControlService;
15
+ export declare class TokenController implements TokenControlService {
16
+ cache: Cache;
17
+ app: Application;
18
+ db: Database;
19
+ logger: SystemLogger;
20
+ constructor({ cache, app, logger }: {
21
+ cache: Cache;
22
+ app: Application;
23
+ logger: SystemLogger;
24
+ });
25
+ setTokenInfo(id: string, value: TokenInfo): Promise<void>;
26
+ getConfig(): Promise<NumericTokenPolicyConfig>;
27
+ setConfig(config: TokenPolicyConfig): Promise<void>;
28
+ removeSessionExpiredTokens(userId: number): Promise<any>;
29
+ add({ userId }: {
30
+ userId: number;
31
+ }): Promise<{
32
+ jti: `${string}-${string}-${string}-${string}-${string}`;
33
+ issuedTime: number;
34
+ signInTime: number;
35
+ renewed: boolean;
36
+ userId: number;
37
+ }>;
38
+ renew: TokenControlService['renew'];
39
+ }
40
+ export {};
@@ -0,0 +1,161 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var token_controller_exports = {};
38
+ __export(token_controller_exports, {
39
+ TokenController: () => TokenController
40
+ });
41
+ module.exports = __toCommonJS(token_controller_exports);
42
+ var import_auth = require("@nocobase/auth");
43
+ var import_crypto = require("crypto");
44
+ var import_ms = __toESM(require("ms"));
45
+ var import_constants = require("../constants");
46
+ const JTICACHEKEY = "token-jti";
47
+ class TokenController {
48
+ cache;
49
+ app;
50
+ db;
51
+ logger;
52
+ constructor({ cache, app, logger }) {
53
+ this.cache = cache;
54
+ this.app = app;
55
+ this.logger = logger;
56
+ }
57
+ async setTokenInfo(id, value) {
58
+ const repo = this.app.db.getRepository(import_constants.issuedTokensCollectionName);
59
+ await repo.updateOrCreate({ filterKeys: ["id"], values: value });
60
+ await this.cache.set(`${JTICACHEKEY}:${id}`, value);
61
+ return;
62
+ }
63
+ getConfig() {
64
+ return this.cache.wrap("config", async () => {
65
+ const repo = this.app.db.getRepository(import_constants.tokenPolicyCollectionName);
66
+ const configRecord = await repo.findOne({ filterByTk: import_constants.tokenPolicyRecordKey });
67
+ if (!configRecord) return null;
68
+ const config = configRecord.config;
69
+ return {
70
+ tokenExpirationTime: (0, import_ms.default)(config.tokenExpirationTime),
71
+ sessionExpirationTime: (0, import_ms.default)(config.sessionExpirationTime),
72
+ expiredTokenRenewLimit: (0, import_ms.default)(config.expiredTokenRenewLimit)
73
+ };
74
+ });
75
+ }
76
+ setConfig(config) {
77
+ return this.cache.set("config", {
78
+ tokenExpirationTime: (0, import_ms.default)(config.tokenExpirationTime),
79
+ sessionExpirationTime: (0, import_ms.default)(config.sessionExpirationTime),
80
+ expiredTokenRenewLimit: (0, import_ms.default)(config.expiredTokenRenewLimit)
81
+ });
82
+ }
83
+ async removeSessionExpiredTokens(userId) {
84
+ const config = await this.getConfig();
85
+ const issuedTokenRepo = this.app.db.getRepository(import_constants.issuedTokensCollectionName);
86
+ const currTS = Date.now();
87
+ return issuedTokenRepo.destroy({
88
+ filter: {
89
+ userId,
90
+ signInTime: {
91
+ $lt: currTS - config.sessionExpirationTime
92
+ }
93
+ }
94
+ });
95
+ }
96
+ async add({ userId }) {
97
+ const jti = (0, import_crypto.randomUUID)();
98
+ const currTS = Date.now();
99
+ const data = {
100
+ jti,
101
+ issuedTime: currTS,
102
+ signInTime: currTS,
103
+ renewed: false,
104
+ userId
105
+ };
106
+ await this.setTokenInfo(jti, data);
107
+ try {
108
+ if (process.env.DB_DIALECT === "sqlite") {
109
+ await this.removeSessionExpiredTokens(userId);
110
+ } else {
111
+ this.removeSessionExpiredTokens(userId);
112
+ }
113
+ } catch (err) {
114
+ this.logger.error(err, { module: "auth", submodule: "token-controller", method: "removeSessionExpiredTokens" });
115
+ }
116
+ return data;
117
+ }
118
+ renew = async (jti) => {
119
+ const repo = this.app.db.getRepository(import_constants.issuedTokensCollectionName);
120
+ const model = this.app.db.getModel(import_constants.issuedTokensCollectionName);
121
+ const exists = await repo.findOne({ filter: { jti } });
122
+ if (!exists) {
123
+ this.logger.error("jti not found", {
124
+ module: "auth",
125
+ submodule: "token-controller",
126
+ method: "renew",
127
+ jti,
128
+ code: import_auth.AuthErrorCode.TOKEN_RENEW_FAILED
129
+ });
130
+ throw new import_auth.AuthError({
131
+ message: "Your session has expired. Please sign in again.",
132
+ code: import_auth.AuthErrorCode.TOKEN_RENEW_FAILED
133
+ });
134
+ }
135
+ const newId = (0, import_crypto.randomUUID)();
136
+ const issuedTime = Date.now();
137
+ const [count] = await model.update(
138
+ { jti: newId, issuedTime },
139
+ { where: { jti } }
140
+ );
141
+ if (count === 1) {
142
+ return { jti: newId, issuedTime };
143
+ } else {
144
+ this.logger.error("jti renew failed", {
145
+ module: "auth",
146
+ submodule: "token-controller",
147
+ method: "renew",
148
+ jti,
149
+ code: import_auth.AuthErrorCode.TOKEN_RENEW_FAILED
150
+ });
151
+ throw new import_auth.AuthError({
152
+ message: "Your session has expired. Please sign in again.",
153
+ code: import_auth.AuthErrorCode.TOKEN_RENEW_FAILED
154
+ });
155
+ }
156
+ };
157
+ }
158
+ // Annotate the CommonJS export names for ESM import in node:
159
+ 0 && (module.exports = {
160
+ TokenController
161
+ });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ export type { TokenPolicyConfig as TokenPolicyConfig } from '@nocobase/auth';
package/dist/types.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from))
17
+ if (!__hasOwnProp.call(to, key) && key !== except)
18
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
+ }
20
+ return to;
21
+ };
22
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
23
+ var types_exports = {};
24
+ module.exports = __toCommonJS(types_exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nocobase/plugin-auth",
3
- "version": "1.6.0-alpha.2",
3
+ "version": "1.6.0-alpha.21",
4
4
  "main": "./dist/server/index.js",
5
5
  "homepage": "https://docs.nocobase.com/handbook/auth",
6
6
  "homepage.zh-CN": "https://docs-cn.nocobase.com/handbook/auth",
@@ -11,6 +11,7 @@
11
11
  "@types/cron": "^2.0.1",
12
12
  "antd": "5.x",
13
13
  "cron": "^2.3.1",
14
+ "ms": "^2.1.3",
14
15
  "react": "^18.2.0",
15
16
  "react-i18next": "^11.15.1"
16
17
  },
@@ -26,8 +27,9 @@
26
27
  "displayName.zh-CN": "用户认证",
27
28
  "description": "User authentication management, including password, SMS, and support for Single Sign-On (SSO) protocols, with extensibility.",
28
29
  "description.zh-CN": "用户认证管理,包括基础的密码认证、短信认证、SSO 协议的认证等,可扩展。",
29
- "gitHead": "08bbc34c21727fc0ad0880f397a42bf7741091ee",
30
+ "gitHead": "873cbaec9554e684781b8dc6cfd4386bb5cfa5b0",
30
31
  "keywords": [
31
- "Authentication"
32
+ "Authentication",
33
+ "Security"
32
34
  ]
33
35
  }