@nocobase/plugin-idp-oauth 2.1.0-alpha.18 → 2.1.0-alpha.20
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/externalVersion.js +6 -4
- package/dist/node_modules/light-my-request/package.json +1 -1
- package/dist/server/collections/oidcStates.d.ts +10 -0
- package/dist/server/collections/oidcStates.js +96 -0
- package/dist/server/db-adapter.d.ts +25 -0
- package/dist/server/db-adapter.js +156 -0
- package/dist/server/service.js +21 -12
- package/package.json +2 -2
- package/dist/server/cache-adapter.d.ts +0 -33
- package/dist/server/cache-adapter.js +0 -159
package/dist/externalVersion.js
CHANGED
|
@@ -11,8 +11,10 @@ module.exports = {
|
|
|
11
11
|
"antd": "5.24.2",
|
|
12
12
|
"react": "18.2.0",
|
|
13
13
|
"react-router-dom": "6.30.1",
|
|
14
|
-
"@nocobase/client": "2.1.0-alpha.
|
|
15
|
-
"@nocobase/flow-engine": "2.1.0-alpha.
|
|
16
|
-
"@nocobase/
|
|
17
|
-
"@nocobase/
|
|
14
|
+
"@nocobase/client": "2.1.0-alpha.20",
|
|
15
|
+
"@nocobase/flow-engine": "2.1.0-alpha.20",
|
|
16
|
+
"@nocobase/server": "2.1.0-alpha.20",
|
|
17
|
+
"@nocobase/cache": "2.1.0-alpha.20",
|
|
18
|
+
"@nocobase/utils": "2.1.0-alpha.20",
|
|
19
|
+
"@nocobase/database": "2.1.0-alpha.20"
|
|
18
20
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"light-my-request","version":"6.6.0","description":"Fake HTTP injection library","main":"index.js","type":"commonjs","types":"types/index.d.ts","dependencies":{"cookie":"^1.0.1","process-warning":"^4.0.0","set-cookie-parser":"^2.6.0"},"devDependencies":{"@fastify/ajv-compiler":"^4.0.0","@fastify/pre-commit":"^2.1.0","@types/node":"^22.7.7","c8":"^10.1.2","end-of-stream":"^1.4.4","eslint":"^9.17.0","express":"^4.19.2","form-auto-content":"^3.2.1","form-data":"^4.0.0","formdata-node":"^6.0.3","multer":"^1.4.5-lts.1","neostandard":"^0.12.0","tinybench":"^3.0.0","tsd":"^0.31.0","undici":"^7.0.0"},"scripts":{"benchmark":"node benchmark/benchmark.js","coverage":"npm run unit -- --cov --coverage-report=html","lint":"eslint","lint:fix":"eslint --fix","test":"npm run lint && npm run test:unit && npm run test:typescript","test:typescript":"tsd","test:unit":"c8 --100 node --test"},"repository":{"type":"git","url":"git+https://github.com/fastify/light-my-request.git"},"keywords":["http","inject","fake","request","server"],"author":"Tomas Della Vedova - @delvedor (http://delved.org)","contributors":[{"name":"Matteo Collina","email":"hello@matteocollina.com"},{"name":"Manuel Spigolon","email":"behemoth89@gmail.com"},{"name":"Aras Abbasi","email":"aras.abbasi@gmail.com"},{"name":"Frazer Smith","email":"frazer.dev@icloud.com","url":"https://github.com/fdawgs"}],"license":"BSD-3-Clause","bugs":{"url":"https://github.com/fastify/light-my-request/issues"},"homepage":"https://github.com/fastify/light-my-request#readme","funding":[{"type":"github","url":"https://github.com/sponsors/fastify"},{"type":"opencollective","url":"https://opencollective.com/fastify"}],"_lastModified":"2026-04-
|
|
1
|
+
{"name":"light-my-request","version":"6.6.0","description":"Fake HTTP injection library","main":"index.js","type":"commonjs","types":"types/index.d.ts","dependencies":{"cookie":"^1.0.1","process-warning":"^4.0.0","set-cookie-parser":"^2.6.0"},"devDependencies":{"@fastify/ajv-compiler":"^4.0.0","@fastify/pre-commit":"^2.1.0","@types/node":"^22.7.7","c8":"^10.1.2","end-of-stream":"^1.4.4","eslint":"^9.17.0","express":"^4.19.2","form-auto-content":"^3.2.1","form-data":"^4.0.0","formdata-node":"^6.0.3","multer":"^1.4.5-lts.1","neostandard":"^0.12.0","tinybench":"^3.0.0","tsd":"^0.31.0","undici":"^7.0.0"},"scripts":{"benchmark":"node benchmark/benchmark.js","coverage":"npm run unit -- --cov --coverage-report=html","lint":"eslint","lint:fix":"eslint --fix","test":"npm run lint && npm run test:unit && npm run test:typescript","test:typescript":"tsd","test:unit":"c8 --100 node --test"},"repository":{"type":"git","url":"git+https://github.com/fastify/light-my-request.git"},"keywords":["http","inject","fake","request","server"],"author":"Tomas Della Vedova - @delvedor (http://delved.org)","contributors":[{"name":"Matteo Collina","email":"hello@matteocollina.com"},{"name":"Manuel Spigolon","email":"behemoth89@gmail.com"},{"name":"Aras Abbasi","email":"aras.abbasi@gmail.com"},{"name":"Frazer Smith","email":"frazer.dev@icloud.com","url":"https://github.com/fdawgs"}],"license":"BSD-3-Clause","bugs":{"url":"https://github.com/fastify/light-my-request/issues"},"homepage":"https://github.com/fastify/light-my-request#readme","funding":[{"type":"github","url":"https://github.com/sponsors/fastify"},{"type":"opencollective","url":"https://opencollective.com/fastify"}],"_lastModified":"2026-04-20T10:42:57.367Z"}
|
|
@@ -0,0 +1,10 @@
|
|
|
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
|
+
declare const _default: import("@nocobase/database").CollectionOptions;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,96 @@
|
|
|
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 __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var oidcStates_exports = {};
|
|
28
|
+
__export(oidcStates_exports, {
|
|
29
|
+
default: () => oidcStates_default
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(oidcStates_exports);
|
|
32
|
+
var import_database = require("@nocobase/database");
|
|
33
|
+
var oidcStates_default = (0, import_database.defineCollection)({
|
|
34
|
+
dumpRules: "required",
|
|
35
|
+
name: "oidcStates",
|
|
36
|
+
migrationRules: ["schema-only"],
|
|
37
|
+
createdAt: true,
|
|
38
|
+
updatedAt: true,
|
|
39
|
+
indexes: [
|
|
40
|
+
{
|
|
41
|
+
unique: true,
|
|
42
|
+
fields: ["model", "oidcId"]
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
fields: ["model", "uid"]
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
fields: ["model", "userCode"]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
fields: ["grantId"]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
fields: ["expiresAt"]
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
fields: [
|
|
58
|
+
{
|
|
59
|
+
type: "string",
|
|
60
|
+
name: "model",
|
|
61
|
+
allowNull: false
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: "string",
|
|
65
|
+
name: "oidcId",
|
|
66
|
+
allowNull: false
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: "json",
|
|
70
|
+
name: "payload",
|
|
71
|
+
allowNull: false
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
type: "string",
|
|
75
|
+
name: "grantId"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
type: "string",
|
|
79
|
+
name: "uid"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
type: "string",
|
|
83
|
+
name: "userCode"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
type: "unixTimestamp",
|
|
87
|
+
name: "expiresAt",
|
|
88
|
+
accuracy: "second"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
type: "unixTimestamp",
|
|
92
|
+
name: "consumedAt",
|
|
93
|
+
accuracy: "second"
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
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 Application from '@nocobase/server';
|
|
10
|
+
export declare function createDbAdapter(app: Application, collectionName?: string): {
|
|
11
|
+
new (model: string): {
|
|
12
|
+
model: string;
|
|
13
|
+
readonly repo: import("@nocobase/database").Repository<any, any>;
|
|
14
|
+
isExpired(record?: any): boolean;
|
|
15
|
+
destroyExpired(record?: any): Promise<void>;
|
|
16
|
+
findRecord(filter: Record<string, any>): Promise<any>;
|
|
17
|
+
destroy(id: string): Promise<void>;
|
|
18
|
+
consume(id: string): Promise<void>;
|
|
19
|
+
find(id: string): Promise<any>;
|
|
20
|
+
findByUid(uid: string): Promise<any>;
|
|
21
|
+
findByUserCode(userCode: string): Promise<any>;
|
|
22
|
+
upsert(id: string, payload: Record<string, any>, expiresIn?: number): Promise<void>;
|
|
23
|
+
revokeByGrantId(grantId: string): Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
@@ -0,0 +1,156 @@
|
|
|
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 __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var db_adapter_exports = {};
|
|
28
|
+
__export(db_adapter_exports, {
|
|
29
|
+
createDbAdapter: () => createDbAdapter
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(db_adapter_exports);
|
|
32
|
+
function epochTime(date = Date.now()) {
|
|
33
|
+
return Math.floor(date / 1e3);
|
|
34
|
+
}
|
|
35
|
+
function createDbAdapter(app, collectionName = "oidcStates") {
|
|
36
|
+
return class DbAdapter {
|
|
37
|
+
model;
|
|
38
|
+
constructor(model) {
|
|
39
|
+
this.model = model;
|
|
40
|
+
}
|
|
41
|
+
get repo() {
|
|
42
|
+
return app.db.getRepository(collectionName);
|
|
43
|
+
}
|
|
44
|
+
isExpired(record) {
|
|
45
|
+
if (!(record == null ? void 0 : record.expiresAt)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
const value = record.expiresAt instanceof Date ? record.expiresAt.getTime() : new Date(record.expiresAt).getTime();
|
|
49
|
+
return value <= Date.now();
|
|
50
|
+
}
|
|
51
|
+
async destroyExpired(record) {
|
|
52
|
+
if (!(record == null ? void 0 : record.id)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
await this.repo.destroy({
|
|
56
|
+
filterByTk: record.id
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
async findRecord(filter) {
|
|
60
|
+
const record = await this.repo.findOne({
|
|
61
|
+
filter
|
|
62
|
+
});
|
|
63
|
+
if (!record) {
|
|
64
|
+
return void 0;
|
|
65
|
+
}
|
|
66
|
+
if (this.isExpired(record)) {
|
|
67
|
+
await this.destroyExpired(record);
|
|
68
|
+
return void 0;
|
|
69
|
+
}
|
|
70
|
+
return record;
|
|
71
|
+
}
|
|
72
|
+
async destroy(id) {
|
|
73
|
+
const record = await this.repo.findOne({
|
|
74
|
+
filter: {
|
|
75
|
+
model: this.model,
|
|
76
|
+
oidcId: id
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
if (!record) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
await this.repo.destroy({
|
|
83
|
+
filterByTk: record.get("id")
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async consume(id) {
|
|
87
|
+
const record = await this.findRecord({
|
|
88
|
+
model: this.model,
|
|
89
|
+
oidcId: id
|
|
90
|
+
});
|
|
91
|
+
if (!record) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const payload = {
|
|
95
|
+
...record.get("payload") || {},
|
|
96
|
+
consumed: epochTime()
|
|
97
|
+
};
|
|
98
|
+
await this.repo.update({
|
|
99
|
+
filterByTk: record.get("id"),
|
|
100
|
+
values: {
|
|
101
|
+
payload,
|
|
102
|
+
consumedAt: Math.floor(Date.now() / 1e3)
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async find(id) {
|
|
107
|
+
const record = await this.findRecord({
|
|
108
|
+
model: this.model,
|
|
109
|
+
oidcId: id
|
|
110
|
+
});
|
|
111
|
+
return record == null ? void 0 : record.get("payload");
|
|
112
|
+
}
|
|
113
|
+
async findByUid(uid) {
|
|
114
|
+
const record = await this.findRecord({
|
|
115
|
+
model: this.model,
|
|
116
|
+
uid
|
|
117
|
+
});
|
|
118
|
+
return record == null ? void 0 : record.get("payload");
|
|
119
|
+
}
|
|
120
|
+
async findByUserCode(userCode) {
|
|
121
|
+
const record = await this.findRecord({
|
|
122
|
+
model: this.model,
|
|
123
|
+
userCode
|
|
124
|
+
});
|
|
125
|
+
return record == null ? void 0 : record.get("payload");
|
|
126
|
+
}
|
|
127
|
+
async upsert(id, payload, expiresIn) {
|
|
128
|
+
await this.repo.updateOrCreate({
|
|
129
|
+
filterKeys: ["model", "oidcId"],
|
|
130
|
+
values: {
|
|
131
|
+
model: this.model,
|
|
132
|
+
oidcId: id,
|
|
133
|
+
payload,
|
|
134
|
+
grantId: payload.grantId || null,
|
|
135
|
+
uid: payload.uid || null,
|
|
136
|
+
userCode: payload.userCode || null,
|
|
137
|
+
expiresAt: typeof expiresIn === "number" && Number.isFinite(expiresIn) ? Math.floor(Date.now() / 1e3) + expiresIn : null
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
async revokeByGrantId(grantId) {
|
|
142
|
+
if (!grantId) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
await this.repo.destroy({
|
|
146
|
+
filter: {
|
|
147
|
+
grantId
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
154
|
+
0 && (module.exports = {
|
|
155
|
+
createDbAdapter
|
|
156
|
+
});
|
package/dist/server/service.js
CHANGED
|
@@ -44,8 +44,9 @@ var import_node_fs = __toESM(require("node:fs"));
|
|
|
44
44
|
var import_light_my_request = __toESM(require("light-my-request"));
|
|
45
45
|
var import_node_crypto = require("node:crypto");
|
|
46
46
|
var import_node_path = __toESM(require("node:path"));
|
|
47
|
-
var
|
|
48
|
-
var
|
|
47
|
+
var import_utils = require("@nocobase/utils");
|
|
48
|
+
var import_db_adapter = require("./db-adapter");
|
|
49
|
+
var import_utils2 = require("./utils");
|
|
49
50
|
let oidcModulePromise = null;
|
|
50
51
|
let joseModulePromise = null;
|
|
51
52
|
function getOidcModule() {
|
|
@@ -79,7 +80,7 @@ class IdpOauthService {
|
|
|
79
80
|
return process.env.APP_PUBLIC_ORIGIN || `${protocol}://${host}`;
|
|
80
81
|
}
|
|
81
82
|
getApiBasePath() {
|
|
82
|
-
return (0,
|
|
83
|
+
return (0, import_utils2.normalizeBasePath)(process.env.API_BASE_PATH || "/api");
|
|
83
84
|
}
|
|
84
85
|
getRequestPath(ctx) {
|
|
85
86
|
var _a, _b;
|
|
@@ -212,30 +213,35 @@ class IdpOauthService {
|
|
|
212
213
|
return void 0;
|
|
213
214
|
}
|
|
214
215
|
const normalizedPath = config.path.startsWith("/") ? config.path : `/${config.path}`;
|
|
215
|
-
return `${(0,
|
|
216
|
+
return `${(0, import_utils2.normalizeBasePath)(process.env.API_BASE_PATH || "/api")}${normalizedPath}`;
|
|
216
217
|
}
|
|
217
218
|
getRequestResourceConfig(ctx) {
|
|
218
|
-
const requestPath = (0,
|
|
219
|
+
const requestPath = (0, import_utils2.normalizeBasePath)(ctx.path || this.getRequestPath(ctx) || "/");
|
|
220
|
+
let matchedConfig;
|
|
221
|
+
let matchedPathLength = -1;
|
|
219
222
|
for (const config of this.resourceServers.values()) {
|
|
220
223
|
const resourcePath = this.getResourcePath(config);
|
|
221
224
|
if (!resourcePath) {
|
|
222
225
|
continue;
|
|
223
226
|
}
|
|
224
|
-
const normalizedResourcePath = (0,
|
|
225
|
-
const isRootResource = normalizedResourcePath === (0,
|
|
227
|
+
const normalizedResourcePath = (0, import_utils2.normalizeBasePath)(resourcePath);
|
|
228
|
+
const isRootResource = normalizedResourcePath === (0, import_utils2.normalizeBasePath)(`${this.getApiBasePath()}/`);
|
|
226
229
|
const matches = requestPath === normalizedResourcePath || requestPath.startsWith(`${normalizedResourcePath}/`) || isRootResource && requestPath.startsWith(`${this.getApiBasePath()}/`);
|
|
227
230
|
if (matches) {
|
|
228
|
-
|
|
231
|
+
if (normalizedResourcePath.length > matchedPathLength) {
|
|
232
|
+
matchedConfig = config;
|
|
233
|
+
matchedPathLength = normalizedResourcePath.length;
|
|
234
|
+
}
|
|
229
235
|
}
|
|
230
236
|
}
|
|
231
|
-
return
|
|
237
|
+
return matchedConfig;
|
|
232
238
|
}
|
|
233
239
|
async getProviderJwks(provider) {
|
|
234
240
|
if (this.resourceJwks.has(provider.issuer)) {
|
|
235
241
|
return this.resourceJwks.get(provider.issuer);
|
|
236
242
|
}
|
|
237
243
|
const { createLocalJWKSet } = await getJoseModule();
|
|
238
|
-
const issuerPath = (0,
|
|
244
|
+
const issuerPath = (0, import_utils2.normalizeBasePath)(new URL(provider.issuer).pathname || "/");
|
|
239
245
|
const jwksPath = provider.pathFor("jwks");
|
|
240
246
|
const internalJwksPath = jwksPath === issuerPath ? "/" : jwksPath.startsWith(`${issuerPath}/`) ? jwksPath.slice(issuerPath.length) || "/" : jwksPath;
|
|
241
247
|
const response = await (0, import_light_my_request.default)(provider.callback(), {
|
|
@@ -267,7 +273,7 @@ class IdpOauthService {
|
|
|
267
273
|
};
|
|
268
274
|
}
|
|
269
275
|
getDefaultJwksPath(appName) {
|
|
270
|
-
return
|
|
276
|
+
return (0, import_utils.storagePathJoin)("apps", appName, "idp_oauth_jwks.json");
|
|
271
277
|
}
|
|
272
278
|
async getProviderSigningJwks(appName) {
|
|
273
279
|
const parseJwks = (value, source) => {
|
|
@@ -444,7 +450,10 @@ class IdpOauthService {
|
|
|
444
450
|
}
|
|
445
451
|
const authorizationHeader = `Bearer ${internalToken}`;
|
|
446
452
|
ctx.req.headers.authorization = authorizationHeader;
|
|
453
|
+
ctx.request.headers.authorization = authorizationHeader;
|
|
454
|
+
ctx.getBearerToken = () => internalToken;
|
|
447
455
|
ctx.req.headers["x-authenticator"] = "basic";
|
|
456
|
+
ctx.request.headers["x-authenticator"] = "basic";
|
|
448
457
|
ctx.state.currentUser = user;
|
|
449
458
|
ctx.auth = ctx.auth || {};
|
|
450
459
|
ctx.auth.user = user;
|
|
@@ -469,7 +478,7 @@ class IdpOauthService {
|
|
|
469
478
|
}
|
|
470
479
|
const jwks = await this.getProviderSigningJwks(appName);
|
|
471
480
|
return {
|
|
472
|
-
adapter: (0,
|
|
481
|
+
adapter: (0, import_db_adapter.createDbAdapter)(this.app, "oidcStates"),
|
|
473
482
|
clients: [],
|
|
474
483
|
scopes: this.getSupportedScopes(),
|
|
475
484
|
jwks,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/plugin-idp-oauth",
|
|
3
|
-
"version": "2.1.0-alpha.
|
|
3
|
+
"version": "2.1.0-alpha.20",
|
|
4
4
|
"main": "dist/server/index.js",
|
|
5
5
|
"displayName": "IdP: OAuth",
|
|
6
6
|
"displayName.zh-CN": "IdP: OAuth",
|
|
@@ -20,5 +20,5 @@
|
|
|
20
20
|
"keywords": [
|
|
21
21
|
"Authentication"
|
|
22
22
|
],
|
|
23
|
-
"gitHead": "
|
|
23
|
+
"gitHead": "3d1535db6bf93ca23257faf474afee0d565f54c6"
|
|
24
24
|
}
|
|
@@ -1,33 +0,0 @@
|
|
|
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 type { Cache } from '@nocobase/cache';
|
|
10
|
-
type StoredPayload = Record<string, any> & {
|
|
11
|
-
__expiresAt?: number;
|
|
12
|
-
};
|
|
13
|
-
export declare function createCacheAdapter(cache: Cache, namespace: string): {
|
|
14
|
-
new (model: string): {
|
|
15
|
-
model: string;
|
|
16
|
-
key(id: string): string;
|
|
17
|
-
read(id: string): Promise<StoredPayload>;
|
|
18
|
-
destroy(id: string): Promise<void>;
|
|
19
|
-
consume(id: string): Promise<void>;
|
|
20
|
-
find(id: string): Promise<{
|
|
21
|
-
[x: string]: any;
|
|
22
|
-
}>;
|
|
23
|
-
findByUid(uid: string): Promise<{
|
|
24
|
-
[x: string]: any;
|
|
25
|
-
}>;
|
|
26
|
-
findByUserCode(userCode: string): Promise<{
|
|
27
|
-
[x: string]: any;
|
|
28
|
-
}>;
|
|
29
|
-
upsert(id: string, payload: Record<string, any>, expiresIn: number): Promise<void>;
|
|
30
|
-
revokeByGrantId(grantId: string): Promise<void>;
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
export {};
|
|
@@ -1,159 +0,0 @@
|
|
|
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 __export = (target, all) => {
|
|
15
|
-
for (var name in all)
|
|
16
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
-
};
|
|
18
|
-
var __copyProps = (to, from, except, desc) => {
|
|
19
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
-
for (let key of __getOwnPropNames(from))
|
|
21
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
-
}
|
|
24
|
-
return to;
|
|
25
|
-
};
|
|
26
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
-
var cache_adapter_exports = {};
|
|
28
|
-
__export(cache_adapter_exports, {
|
|
29
|
-
createCacheAdapter: () => createCacheAdapter
|
|
30
|
-
});
|
|
31
|
-
module.exports = __toCommonJS(cache_adapter_exports);
|
|
32
|
-
const grantable = /* @__PURE__ */ new Set([
|
|
33
|
-
"AccessToken",
|
|
34
|
-
"AuthorizationCode",
|
|
35
|
-
"RefreshToken",
|
|
36
|
-
"DeviceCode",
|
|
37
|
-
"BackchannelAuthenticationRequest"
|
|
38
|
-
]);
|
|
39
|
-
function epochTime(date = Date.now()) {
|
|
40
|
-
return Math.floor(date / 1e3);
|
|
41
|
-
}
|
|
42
|
-
function createCacheAdapter(cache, namespace) {
|
|
43
|
-
const keyFor = (model, id) => `${namespace}:${model}:${id}`;
|
|
44
|
-
const grantKeyFor = (grantId) => `${namespace}:grant:${grantId}`;
|
|
45
|
-
const sessionUidKeyFor = (uid) => `${namespace}:sessionUid:${uid}`;
|
|
46
|
-
const userCodeKeyFor = (userCode) => `${namespace}:userCode:${userCode}`;
|
|
47
|
-
const normalize = (payload) => {
|
|
48
|
-
if (!payload) {
|
|
49
|
-
return void 0;
|
|
50
|
-
}
|
|
51
|
-
if (payload.__expiresAt && payload.__expiresAt <= Date.now()) {
|
|
52
|
-
return void 0;
|
|
53
|
-
}
|
|
54
|
-
const { __expiresAt, ...data } = payload;
|
|
55
|
-
return data;
|
|
56
|
-
};
|
|
57
|
-
const getRemainingTtl = (payload) => {
|
|
58
|
-
if (!(payload == null ? void 0 : payload.__expiresAt)) {
|
|
59
|
-
return void 0;
|
|
60
|
-
}
|
|
61
|
-
const ttl = payload.__expiresAt - Date.now();
|
|
62
|
-
return ttl > 0 ? ttl : void 0;
|
|
63
|
-
};
|
|
64
|
-
return class CacheAdapter {
|
|
65
|
-
model;
|
|
66
|
-
constructor(model) {
|
|
67
|
-
this.model = model;
|
|
68
|
-
}
|
|
69
|
-
key(id) {
|
|
70
|
-
return keyFor(this.model, id);
|
|
71
|
-
}
|
|
72
|
-
async read(id) {
|
|
73
|
-
const payload = await cache.get(this.key(id));
|
|
74
|
-
if (!payload) {
|
|
75
|
-
return void 0;
|
|
76
|
-
}
|
|
77
|
-
if (payload.__expiresAt && payload.__expiresAt <= Date.now()) {
|
|
78
|
-
await this.destroy(id);
|
|
79
|
-
return void 0;
|
|
80
|
-
}
|
|
81
|
-
return payload;
|
|
82
|
-
}
|
|
83
|
-
async destroy(id) {
|
|
84
|
-
const payload = await cache.get(this.key(id));
|
|
85
|
-
await cache.del(this.key(id));
|
|
86
|
-
if ((payload == null ? void 0 : payload.uid) && this.model === "Session") {
|
|
87
|
-
await cache.del(sessionUidKeyFor(payload.uid));
|
|
88
|
-
}
|
|
89
|
-
if (payload == null ? void 0 : payload.userCode) {
|
|
90
|
-
await cache.del(userCodeKeyFor(payload.userCode));
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
async consume(id) {
|
|
94
|
-
const payload = await this.read(id);
|
|
95
|
-
if (!payload) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
payload.consumed = epochTime();
|
|
99
|
-
await cache.set(this.key(id), payload, getRemainingTtl(payload));
|
|
100
|
-
}
|
|
101
|
-
async find(id) {
|
|
102
|
-
return normalize(await this.read(id));
|
|
103
|
-
}
|
|
104
|
-
async findByUid(uid) {
|
|
105
|
-
const id = await cache.get(sessionUidKeyFor(uid));
|
|
106
|
-
if (!id) {
|
|
107
|
-
return void 0;
|
|
108
|
-
}
|
|
109
|
-
return this.find(id);
|
|
110
|
-
}
|
|
111
|
-
async findByUserCode(userCode) {
|
|
112
|
-
const id = await cache.get(userCodeKeyFor(userCode));
|
|
113
|
-
if (!id) {
|
|
114
|
-
return void 0;
|
|
115
|
-
}
|
|
116
|
-
return this.find(id);
|
|
117
|
-
}
|
|
118
|
-
async upsert(id, payload, expiresIn) {
|
|
119
|
-
const ttl = expiresIn * 1e3;
|
|
120
|
-
const stored = {
|
|
121
|
-
...payload,
|
|
122
|
-
__expiresAt: Date.now() + ttl
|
|
123
|
-
};
|
|
124
|
-
if (this.model === "Session" && payload.uid) {
|
|
125
|
-
await cache.set(sessionUidKeyFor(payload.uid), id, ttl);
|
|
126
|
-
}
|
|
127
|
-
if (grantable.has(this.model) && payload.grantId) {
|
|
128
|
-
const grantKey = grantKeyFor(payload.grantId);
|
|
129
|
-
const grant = (await cache.get(grantKey) || []).filter(Boolean);
|
|
130
|
-
if (!grant.includes(this.key(id))) {
|
|
131
|
-
grant.push(this.key(id));
|
|
132
|
-
}
|
|
133
|
-
await cache.set(grantKey, grant, ttl);
|
|
134
|
-
}
|
|
135
|
-
if (payload.userCode) {
|
|
136
|
-
await cache.set(userCodeKeyFor(payload.userCode), id, ttl);
|
|
137
|
-
}
|
|
138
|
-
await cache.set(this.key(id), stored, ttl);
|
|
139
|
-
}
|
|
140
|
-
async revokeByGrantId(grantId) {
|
|
141
|
-
const grantKey = grantKeyFor(grantId);
|
|
142
|
-
const grant = await cache.get(grantKey);
|
|
143
|
-
if (!(grant == null ? void 0 : grant.length)) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
await Promise.all(
|
|
147
|
-
grant.map((tokenKey) => {
|
|
148
|
-
const id = tokenKey.slice(this.key("").length);
|
|
149
|
-
return this.destroy(id);
|
|
150
|
-
})
|
|
151
|
-
);
|
|
152
|
-
await cache.del(grantKey);
|
|
153
|
-
}
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
157
|
-
0 && (module.exports = {
|
|
158
|
-
createCacheAdapter
|
|
159
|
-
});
|