@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.
- package/dist/client/{938.index.js → 0091d4359312cb07.js} +1 -1
- package/dist/client/88ef1c520c08b674.js +10 -0
- package/dist/client/{851.index.js → 974ac9de644a1d1f.js} +1 -1
- package/dist/client/{280.index.js → 9e603524b127e7b4.js} +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/interceptors.d.ts +13 -0
- package/dist/client/settings/token-policy/components.d.ts +15 -0
- package/dist/client/settings/token-policy/hooks.d.ts +24 -0
- package/dist/client/settings/token-policy/index.d.ts +10 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.js +45 -0
- package/dist/externalVersion.js +11 -8
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -2
- package/dist/locale/en-US.json +18 -1
- package/dist/locale/zh-CN.json +17 -1
- package/dist/node_modules/cron/package.json +1 -1
- package/dist/node_modules/ms/index.js +1 -0
- package/dist/node_modules/ms/package.json +1 -0
- package/dist/server/actions/auth.js +6 -0
- package/dist/server/basic-auth.js +4 -1
- package/dist/server/collections/authenticators.js +1 -0
- package/dist/server/collections/issued-tokens.d.ts +10 -0
- package/dist/server/collections/issued-tokens.js +70 -0
- package/dist/server/collections/token-blacklist.js +1 -0
- package/dist/server/collections/token-poilcy-config.d.ts +10 -0
- package/dist/server/collections/token-poilcy-config.js +57 -0
- package/dist/server/collections/users-authenticators.js +1 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +8 -2
- package/dist/server/migrations/20241229080941-create-token-policy-config.d.ts +14 -0
- package/dist/server/migrations/20241229080941-create-token-policy-config.js +58 -0
- package/dist/server/plugin.js +107 -54
- package/dist/server/storer.d.ts +8 -2
- package/dist/server/storer.js +28 -3
- package/dist/server/token-blacklist.js +13 -2
- package/dist/server/token-controller.d.ts +40 -0
- package/dist/server/token-controller.js +161 -0
- package/dist/types.d.ts +9 -0
- package/dist/types.js +24 -0
- package/package.json +5 -3
- /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({
|
|
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.
|
|
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
|
+
});
|
package/dist/types.d.ts
ADDED
|
@@ -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.
|
|
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": "
|
|
30
|
+
"gitHead": "873cbaec9554e684781b8dc6cfd4386bb5cfa5b0",
|
|
30
31
|
"keywords": [
|
|
31
|
-
"Authentication"
|
|
32
|
+
"Authentication",
|
|
33
|
+
"Security"
|
|
32
34
|
]
|
|
33
35
|
}
|
|
File without changes
|