@ruiapp/rapid-core 0.5.7 → 0.5.9
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/facilities/cache/CacheFacilityTypes.d.ts +11 -0
- package/dist/facilities/cache/CacheFactory.d.ts +8 -0
- package/dist/facilities/cache/MemoryCache.d.ts +10 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +200 -8
- package/dist/plugins/auth/AuthPlugin.d.ts +2 -0
- package/dist/plugins/auth/actionHandlers/createSession.d.ts +0 -4
- package/dist/plugins/auth/services/AuthService.d.ts +15 -0
- package/package.json +1 -1
- package/src/facilities/cache/CacheFacilityTypes.ts +12 -0
- package/src/facilities/cache/CacheFactory.ts +15 -0
- package/src/facilities/cache/MemoryCache.ts +42 -0
- package/src/index.ts +5 -0
- package/src/plugins/auth/AuthPlugin.ts +8 -0
- package/src/plugins/auth/actionHandlers/createSession.ts +7 -17
- package/src/plugins/auth/services/AuthService.ts +39 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface CacheProvider {
|
|
2
|
+
set: (key: string, value: any, options?: SetValueOptions) => Promise<void>;
|
|
3
|
+
get: (key: string) => Promise<any>;
|
|
4
|
+
del: (key: string) => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export interface SetValueOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Time-to-live, in milliseconds
|
|
9
|
+
*/
|
|
10
|
+
ttl?: number;
|
|
11
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FacilityFactory } from "../../core/facility";
|
|
2
|
+
import { IRpdServer } from "../../core/server";
|
|
3
|
+
import MemoryCache from "./MemoryCache";
|
|
4
|
+
export default class CacheFactory implements FacilityFactory {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
constructor();
|
|
7
|
+
createFacility(server: IRpdServer, options?: any): Promise<MemoryCache>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CacheProvider, SetValueOptions } from "./CacheFacilityTypes";
|
|
2
|
+
export type MemoryCacheItem<TValue = any> = {
|
|
3
|
+
value: TValue;
|
|
4
|
+
expireAt: number;
|
|
5
|
+
};
|
|
6
|
+
export default class MemoryCache implements CacheProvider {
|
|
7
|
+
set(key: string, value: any, options?: SetValueOptions): Promise<void>;
|
|
8
|
+
get(key: string): Promise<any>;
|
|
9
|
+
del(key: string): Promise<void>;
|
|
10
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,8 +6,11 @@ export * from "./core/server";
|
|
|
6
6
|
export * from "./core/http-types";
|
|
7
7
|
export * from "./core/actionHandler";
|
|
8
8
|
export * from "./utilities/jwtUtility";
|
|
9
|
+
export * from "./deno-std/http/cookie";
|
|
9
10
|
export { mapDbRowToEntity } from "./dataAccess/entityMapper";
|
|
10
11
|
export * as bootstrapApplicationConfig from "./bootstrapApplicationConfig";
|
|
12
|
+
export { default as CacheFactory } from "./facilities/cache/CacheFactory";
|
|
13
|
+
export * from "./facilities/cache/CacheFacilityTypes";
|
|
11
14
|
export { default as MetaManagePlugin } from "./plugins/metaManage/MetaManagePlugin";
|
|
12
15
|
export { default as DataManagePlugin } from "./plugins/dataManage/DataManagePlugin";
|
|
13
16
|
export { default as RouteManagePlugin } from "./plugins/routeManage/RouteManagePlugin";
|
package/dist/index.js
CHANGED
|
@@ -1402,6 +1402,130 @@ function setCookie(headers, cookie) {
|
|
|
1402
1402
|
if (v) {
|
|
1403
1403
|
headers.append("Set-Cookie", v);
|
|
1404
1404
|
}
|
|
1405
|
+
}
|
|
1406
|
+
/**
|
|
1407
|
+
* Set the cookie header with empty value in the headers to delete it
|
|
1408
|
+
*
|
|
1409
|
+
* > Note: Deleting a `Cookie` will set its expiration date before now. Forcing
|
|
1410
|
+
* > the browser to delete it.
|
|
1411
|
+
*
|
|
1412
|
+
* @example
|
|
1413
|
+
* ```ts
|
|
1414
|
+
* import { deleteCookie } from "https://deno.land/std@$STD_VERSION/http/cookie.ts";
|
|
1415
|
+
*
|
|
1416
|
+
* const headers = new Headers();
|
|
1417
|
+
* deleteCookie(headers, "deno");
|
|
1418
|
+
*
|
|
1419
|
+
* const cookieHeader = headers.get("set-cookie");
|
|
1420
|
+
* console.log(cookieHeader); // deno=; Expires=Thus, 01 Jan 1970 00:00:00 GMT
|
|
1421
|
+
* ```
|
|
1422
|
+
*
|
|
1423
|
+
* @param headers The headers instance to delete the cookie from
|
|
1424
|
+
* @param name Name of cookie
|
|
1425
|
+
* @param attributes Additional cookie attributes
|
|
1426
|
+
*/
|
|
1427
|
+
function deleteCookie(headers, name, attributes) {
|
|
1428
|
+
setCookie(headers, {
|
|
1429
|
+
name: name,
|
|
1430
|
+
value: "",
|
|
1431
|
+
expires: new Date(0),
|
|
1432
|
+
...attributes,
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
1435
|
+
function parseSetCookie(value) {
|
|
1436
|
+
const attrs = value.split(";").map((attr) => {
|
|
1437
|
+
const [key, ...values] = attr.trim().split("=");
|
|
1438
|
+
return [key, values.join("=")];
|
|
1439
|
+
});
|
|
1440
|
+
const cookie = {
|
|
1441
|
+
name: attrs[0][0],
|
|
1442
|
+
value: attrs[0][1],
|
|
1443
|
+
};
|
|
1444
|
+
for (const [key, value] of attrs.slice(1)) {
|
|
1445
|
+
switch (key.toLocaleLowerCase()) {
|
|
1446
|
+
case "expires":
|
|
1447
|
+
cookie.expires = new Date(value);
|
|
1448
|
+
break;
|
|
1449
|
+
case "max-age":
|
|
1450
|
+
cookie.maxAge = Number(value);
|
|
1451
|
+
if (cookie.maxAge < 0) {
|
|
1452
|
+
console.warn("Max-Age must be an integer superior or equal to 0. Cookie ignored.");
|
|
1453
|
+
return null;
|
|
1454
|
+
}
|
|
1455
|
+
break;
|
|
1456
|
+
case "domain":
|
|
1457
|
+
cookie.domain = value;
|
|
1458
|
+
break;
|
|
1459
|
+
case "path":
|
|
1460
|
+
cookie.path = value;
|
|
1461
|
+
break;
|
|
1462
|
+
case "secure":
|
|
1463
|
+
cookie.secure = true;
|
|
1464
|
+
break;
|
|
1465
|
+
case "httponly":
|
|
1466
|
+
cookie.httpOnly = true;
|
|
1467
|
+
break;
|
|
1468
|
+
case "samesite":
|
|
1469
|
+
cookie.sameSite = value;
|
|
1470
|
+
break;
|
|
1471
|
+
default:
|
|
1472
|
+
if (!Array.isArray(cookie.unparsed)) {
|
|
1473
|
+
cookie.unparsed = [];
|
|
1474
|
+
}
|
|
1475
|
+
cookie.unparsed.push([key, value].join("="));
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
if (cookie.name.startsWith("__Secure-")) {
|
|
1479
|
+
/** This requirement is mentioned in https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie but not the RFC. */
|
|
1480
|
+
if (!cookie.secure) {
|
|
1481
|
+
console.warn("Cookies with names starting with `__Secure-` must be set with the secure flag. Cookie ignored.");
|
|
1482
|
+
return null;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
if (cookie.name.startsWith("__Host-")) {
|
|
1486
|
+
if (!cookie.secure) {
|
|
1487
|
+
console.warn("Cookies with names starting with `__Host-` must be set with the secure flag. Cookie ignored.");
|
|
1488
|
+
return null;
|
|
1489
|
+
}
|
|
1490
|
+
if (cookie.domain !== undefined) {
|
|
1491
|
+
console.warn("Cookies with names starting with `__Host-` must not have a domain specified. Cookie ignored.");
|
|
1492
|
+
return null;
|
|
1493
|
+
}
|
|
1494
|
+
if (cookie.path !== "/") {
|
|
1495
|
+
console.warn("Cookies with names starting with `__Host-` must have path be `/`. Cookie has been ignored.");
|
|
1496
|
+
return null;
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
return cookie;
|
|
1500
|
+
}
|
|
1501
|
+
/**
|
|
1502
|
+
* Parse set-cookies of a header
|
|
1503
|
+
*
|
|
1504
|
+
* @example
|
|
1505
|
+
* ```ts
|
|
1506
|
+
* import { getSetCookies } from "https://deno.land/std@$STD_VERSION/http/cookie.ts";
|
|
1507
|
+
*
|
|
1508
|
+
* const headers = new Headers([
|
|
1509
|
+
* ["Set-Cookie", "lulu=meow; Secure; Max-Age=3600"],
|
|
1510
|
+
* ["Set-Cookie", "booya=kasha; HttpOnly; Path=/"],
|
|
1511
|
+
* ]);
|
|
1512
|
+
*
|
|
1513
|
+
* const cookies = getSetCookies(headers);
|
|
1514
|
+
* console.log(cookies); // [{ name: "lulu", value: "meow", secure: true, maxAge: 3600 }, { name: "booya", value: "kahsa", httpOnly: true, path: "/ }]
|
|
1515
|
+
* ```
|
|
1516
|
+
*
|
|
1517
|
+
* @param headers The headers instance to get set-cookies from
|
|
1518
|
+
* @return List of cookies
|
|
1519
|
+
*/
|
|
1520
|
+
function getSetCookies(headers) {
|
|
1521
|
+
// TODO(lino-levan): remove this ts-ignore when Typescript 5.2 lands in Deno
|
|
1522
|
+
// @ts-ignore Typescript's TS Dom types will be out of date until 5.2
|
|
1523
|
+
return headers
|
|
1524
|
+
.getSetCookie()
|
|
1525
|
+
/** Parse each `set-cookie` header separately */
|
|
1526
|
+
.map(parseSetCookie)
|
|
1527
|
+
/** Skip empty cookies */
|
|
1528
|
+
.filter(Boolean);
|
|
1405
1529
|
}
|
|
1406
1530
|
|
|
1407
1531
|
const GlobalRequest = global.Request;
|
|
@@ -4530,6 +4654,46 @@ async function generateJwtSecretKey() {
|
|
|
4530
4654
|
return encode(exportedKey);
|
|
4531
4655
|
}
|
|
4532
4656
|
|
|
4657
|
+
const values = new Map();
|
|
4658
|
+
class MemoryCache {
|
|
4659
|
+
async set(key, value, options) {
|
|
4660
|
+
let expireAt = -1;
|
|
4661
|
+
if (options && options.ttl > 0) {
|
|
4662
|
+
expireAt = new Date().valueOf() + options.ttl;
|
|
4663
|
+
}
|
|
4664
|
+
const cacheItem = {
|
|
4665
|
+
value,
|
|
4666
|
+
expireAt,
|
|
4667
|
+
};
|
|
4668
|
+
values.set(key, cacheItem);
|
|
4669
|
+
}
|
|
4670
|
+
async get(key) {
|
|
4671
|
+
const cacheItem = values.get(key);
|
|
4672
|
+
if (cacheItem) {
|
|
4673
|
+
if (cacheItem.expireAt === -1) {
|
|
4674
|
+
return cacheItem.value;
|
|
4675
|
+
}
|
|
4676
|
+
if (cacheItem.expireAt >= new Date().valueOf()) {
|
|
4677
|
+
return cacheItem.value;
|
|
4678
|
+
}
|
|
4679
|
+
}
|
|
4680
|
+
return undefined;
|
|
4681
|
+
}
|
|
4682
|
+
async del(key) {
|
|
4683
|
+
values.delete(key);
|
|
4684
|
+
}
|
|
4685
|
+
}
|
|
4686
|
+
|
|
4687
|
+
class CacheFactory {
|
|
4688
|
+
name;
|
|
4689
|
+
constructor() {
|
|
4690
|
+
this.name = "cache";
|
|
4691
|
+
}
|
|
4692
|
+
async createFacility(server, options) {
|
|
4693
|
+
return new MemoryCache();
|
|
4694
|
+
}
|
|
4695
|
+
}
|
|
4696
|
+
|
|
4533
4697
|
const code$u = "listMetaModels";
|
|
4534
4698
|
async function handler$u(plugin, ctx, options) {
|
|
4535
4699
|
const { applicationConfig } = ctx;
|
|
@@ -6298,14 +6462,12 @@ async function handler$d(plugin, ctx, options) {
|
|
|
6298
6462
|
if (!isMatch) {
|
|
6299
6463
|
throw new Error("用户名或密码错误。");
|
|
6300
6464
|
}
|
|
6301
|
-
const
|
|
6302
|
-
const token =
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
act: user.login,
|
|
6308
|
-
}, secretKey);
|
|
6465
|
+
const authService = server.getService("authService");
|
|
6466
|
+
const token = authService.createUserAccessToken({
|
|
6467
|
+
issuer: "authManager",
|
|
6468
|
+
userId: user.id,
|
|
6469
|
+
userLogin: user.login,
|
|
6470
|
+
});
|
|
6309
6471
|
setCookie(response.headers, {
|
|
6310
6472
|
name: ctx.server.config.sessionCookieName,
|
|
6311
6473
|
value: token,
|
|
@@ -6539,10 +6701,31 @@ var signout$1 = {
|
|
|
6539
6701
|
|
|
6540
6702
|
var pluginRoutes$7 = [changePassword, getMyProfile$1, resetPassword, signin$1, signout$1];
|
|
6541
6703
|
|
|
6704
|
+
class AuthService {
|
|
6705
|
+
#server;
|
|
6706
|
+
#jwtKey;
|
|
6707
|
+
constructor(server, jwtKey) {
|
|
6708
|
+
this.#server = server;
|
|
6709
|
+
this.#jwtKey = jwtKey;
|
|
6710
|
+
}
|
|
6711
|
+
createUserAccessToken(options) {
|
|
6712
|
+
const secretKey = Buffer.from(this.#jwtKey, "base64");
|
|
6713
|
+
const token = createJwt({
|
|
6714
|
+
iss: options.issuer,
|
|
6715
|
+
sub: "userAccessToken",
|
|
6716
|
+
aud: "" + options.userId,
|
|
6717
|
+
iat: Math.floor(Date.now() / 1000),
|
|
6718
|
+
act: options.userLogin,
|
|
6719
|
+
}, secretKey);
|
|
6720
|
+
return token;
|
|
6721
|
+
}
|
|
6722
|
+
}
|
|
6723
|
+
|
|
6542
6724
|
/**
|
|
6543
6725
|
* Auth manager plugin
|
|
6544
6726
|
*/
|
|
6545
6727
|
class AuthPlugin {
|
|
6728
|
+
#authService;
|
|
6546
6729
|
get code() {
|
|
6547
6730
|
return "authManager";
|
|
6548
6731
|
}
|
|
@@ -6566,6 +6749,10 @@ class AuthPlugin {
|
|
|
6566
6749
|
async configureModels(server, applicationConfig) {
|
|
6567
6750
|
server.appendApplicationConfig({ models: pluginModels$5 });
|
|
6568
6751
|
}
|
|
6752
|
+
async configureServices(server, applicationConfig) {
|
|
6753
|
+
this.#authService = new AuthService(server, server.config.jwtKey);
|
|
6754
|
+
server.registerService("authService", this.#authService);
|
|
6755
|
+
}
|
|
6569
6756
|
async configureRoutes(server, applicationConfig) {
|
|
6570
6757
|
server.appendApplicationConfig({ routes: pluginRoutes$7 });
|
|
6571
6758
|
}
|
|
@@ -8528,6 +8715,7 @@ class EntityAccessControlPlugin {
|
|
|
8528
8715
|
fixBigIntJSONSerialize();
|
|
8529
8716
|
|
|
8530
8717
|
exports.AuthPlugin = AuthPlugin;
|
|
8718
|
+
exports.CacheFactory = CacheFactory;
|
|
8531
8719
|
exports.CronJobPlugin = CronJobPlugin;
|
|
8532
8720
|
exports.DataManagePlugin = DataManager;
|
|
8533
8721
|
exports.EntityAccessControlPlugin = EntityAccessControlPlugin;
|
|
@@ -8549,6 +8737,10 @@ exports.WebhooksPlugin = WebhooksPlugin;
|
|
|
8549
8737
|
exports.bootstrapApplicationConfig = bootstrapApplicationConfig$1;
|
|
8550
8738
|
exports.createJwt = createJwt;
|
|
8551
8739
|
exports.decodeJwt = decodeJwt;
|
|
8740
|
+
exports.deleteCookie = deleteCookie;
|
|
8552
8741
|
exports.generateJwtSecretKey = generateJwtSecretKey;
|
|
8742
|
+
exports.getCookies = getCookies;
|
|
8743
|
+
exports.getSetCookies = getSetCookies;
|
|
8553
8744
|
exports.mapDbRowToEntity = mapDbRowToEntity;
|
|
8745
|
+
exports.setCookie = setCookie;
|
|
8554
8746
|
exports.verifyJwt = verifyJwt;
|
|
@@ -5,6 +5,7 @@ import { RpdApplicationConfig } from "../../types";
|
|
|
5
5
|
import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "../../core/server";
|
|
6
6
|
import { RouteContext } from "../../core/routeContext";
|
|
7
7
|
declare class AuthPlugin implements RapidPlugin {
|
|
8
|
+
#private;
|
|
8
9
|
get code(): string;
|
|
9
10
|
get description(): string;
|
|
10
11
|
get extendingAbilities(): RpdServerPluginExtendingAbilities[];
|
|
@@ -12,6 +13,7 @@ declare class AuthPlugin implements RapidPlugin {
|
|
|
12
13
|
get configurations(): RpdConfigurationItemOptions[];
|
|
13
14
|
registerActionHandlers(server: IRpdServer): Promise<any>;
|
|
14
15
|
configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
|
|
16
|
+
configureServices(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
|
|
15
17
|
configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
|
|
16
18
|
onPrepareRouteContext(server: IRpdServer, routeContext: RouteContext): Promise<void>;
|
|
17
19
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
2
2
|
import { RapidPlugin } from "../../../core/server";
|
|
3
|
-
export interface UserAccessToken {
|
|
4
|
-
sub: "userAccessToken";
|
|
5
|
-
aud: string;
|
|
6
|
-
}
|
|
7
3
|
export declare const code = "createSession";
|
|
8
4
|
export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: any): Promise<void>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { IRpdServer } from "../../../core/server";
|
|
2
|
+
export interface UserAccessToken {
|
|
3
|
+
sub: "userAccessToken";
|
|
4
|
+
aud: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CreateUserAccessTokenOptions {
|
|
7
|
+
issuer: string;
|
|
8
|
+
userId: number;
|
|
9
|
+
userLogin: string;
|
|
10
|
+
}
|
|
11
|
+
export default class AuthService {
|
|
12
|
+
#private;
|
|
13
|
+
constructor(server: IRpdServer, jwtKey: string);
|
|
14
|
+
createUserAccessToken(options: CreateUserAccessTokenOptions): string;
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface CacheProvider {
|
|
2
|
+
set: (key: string, value: any, options?: SetValueOptions) => Promise<void>;
|
|
3
|
+
get: (key: string) => Promise<any>;
|
|
4
|
+
del: (key: string) => Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface SetValueOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Time-to-live, in milliseconds
|
|
10
|
+
*/
|
|
11
|
+
ttl?: number;
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { FacilityFactory } from "~/core/facility";
|
|
2
|
+
import { IRpdServer } from "~/core/server";
|
|
3
|
+
import MemoryCache from "./MemoryCache";
|
|
4
|
+
|
|
5
|
+
export default class CacheFactory implements FacilityFactory {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
|
|
8
|
+
constructor() {
|
|
9
|
+
this.name = "cache";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async createFacility(server: IRpdServer, options?: any) {
|
|
13
|
+
return new MemoryCache();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CacheProvider, SetValueOptions } from "./CacheFacilityTypes";
|
|
2
|
+
|
|
3
|
+
export type MemoryCacheItem<TValue = any> = {
|
|
4
|
+
value: TValue;
|
|
5
|
+
expireAt: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const values: Map<string, MemoryCacheItem> = new Map();
|
|
9
|
+
|
|
10
|
+
export default class MemoryCache implements CacheProvider {
|
|
11
|
+
async set(key: string, value: any, options?: SetValueOptions) {
|
|
12
|
+
let expireAt = -1;
|
|
13
|
+
if (options && options.ttl > 0) {
|
|
14
|
+
expireAt = new Date().valueOf() + options.ttl;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const cacheItem = {
|
|
18
|
+
value,
|
|
19
|
+
expireAt,
|
|
20
|
+
};
|
|
21
|
+
values.set(key, cacheItem);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async get(key: string) {
|
|
25
|
+
const cacheItem = values.get(key);
|
|
26
|
+
if (cacheItem) {
|
|
27
|
+
if (cacheItem.expireAt === -1) {
|
|
28
|
+
return cacheItem.value;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (cacheItem.expireAt >= new Date().valueOf()) {
|
|
32
|
+
return cacheItem.value;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async del(key: string) {
|
|
40
|
+
values.delete(key);
|
|
41
|
+
}
|
|
42
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -12,10 +12,15 @@ export * from "./core/actionHandler";
|
|
|
12
12
|
|
|
13
13
|
export * from "./utilities/jwtUtility";
|
|
14
14
|
|
|
15
|
+
export * from "./deno-std/http/cookie";
|
|
16
|
+
|
|
15
17
|
export { mapDbRowToEntity } from "./dataAccess/entityMapper";
|
|
16
18
|
|
|
17
19
|
export * as bootstrapApplicationConfig from "./bootstrapApplicationConfig";
|
|
18
20
|
|
|
21
|
+
export { default as CacheFactory } from "./facilities/cache/CacheFactory";
|
|
22
|
+
export * from "./facilities/cache/CacheFacilityTypes";
|
|
23
|
+
|
|
19
24
|
export { default as MetaManagePlugin } from "./plugins/metaManage/MetaManagePlugin";
|
|
20
25
|
|
|
21
26
|
export { default as DataManagePlugin } from "./plugins/dataManage/DataManagePlugin";
|
|
@@ -16,8 +16,11 @@ import pluginModels from "./models";
|
|
|
16
16
|
import pluginRoutes from "./routes";
|
|
17
17
|
import { RouteContext } from "~/core/routeContext";
|
|
18
18
|
import { verifyJwt } from "~/utilities/jwtUtility";
|
|
19
|
+
import AuthService from "./services/AuthService";
|
|
19
20
|
|
|
20
21
|
class AuthPlugin implements RapidPlugin {
|
|
22
|
+
#authService!: AuthService;
|
|
23
|
+
|
|
21
24
|
get code(): string {
|
|
22
25
|
return "authManager";
|
|
23
26
|
}
|
|
@@ -48,6 +51,11 @@ class AuthPlugin implements RapidPlugin {
|
|
|
48
51
|
server.appendApplicationConfig({ models: pluginModels });
|
|
49
52
|
}
|
|
50
53
|
|
|
54
|
+
async configureServices(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
|
|
55
|
+
this.#authService = new AuthService(server, server.config.jwtKey);
|
|
56
|
+
server.registerService("authService", this.#authService);
|
|
57
|
+
}
|
|
58
|
+
|
|
51
59
|
async configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
|
|
52
60
|
server.appendApplicationConfig({ routes: pluginRoutes });
|
|
53
61
|
}
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
import bcrypt from "bcrypt";
|
|
2
2
|
import { setCookie } from "~/deno-std/http/cookie";
|
|
3
|
-
import { createJwt } from "~/utilities/jwtUtility";
|
|
4
3
|
import { ActionHandlerContext } from "~/core/actionHandler";
|
|
5
4
|
import { RapidPlugin } from "~/core/server";
|
|
6
5
|
import LicenseService from "~/plugins/license/LicenseService";
|
|
7
6
|
import { get } from "lodash";
|
|
8
|
-
|
|
9
|
-
export interface UserAccessToken {
|
|
10
|
-
sub: "userAccessToken";
|
|
11
|
-
aud: string;
|
|
12
|
-
}
|
|
7
|
+
import AuthService from "../services/AuthService";
|
|
13
8
|
|
|
14
9
|
export const code = "createSession";
|
|
15
10
|
|
|
@@ -54,17 +49,12 @@ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, op
|
|
|
54
49
|
throw new Error("用户名或密码错误。");
|
|
55
50
|
}
|
|
56
51
|
|
|
57
|
-
const
|
|
58
|
-
const token =
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
iat: Math.floor(Date.now() / 1000),
|
|
64
|
-
act: user.login,
|
|
65
|
-
} as UserAccessToken,
|
|
66
|
-
secretKey,
|
|
67
|
-
);
|
|
52
|
+
const authService = server.getService<AuthService>("authService");
|
|
53
|
+
const token = authService.createUserAccessToken({
|
|
54
|
+
issuer: "authManager",
|
|
55
|
+
userId: user.id,
|
|
56
|
+
userLogin: user.login,
|
|
57
|
+
});
|
|
68
58
|
|
|
69
59
|
setCookie(response.headers, {
|
|
70
60
|
name: ctx.server.config.sessionCookieName,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { IRpdServer } from "~/core/server";
|
|
2
|
+
import { createJwt } from "~/utilities/jwtUtility";
|
|
3
|
+
|
|
4
|
+
export interface UserAccessToken {
|
|
5
|
+
sub: "userAccessToken";
|
|
6
|
+
aud: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface CreateUserAccessTokenOptions {
|
|
10
|
+
issuer: string;
|
|
11
|
+
userId: number;
|
|
12
|
+
userLogin: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default class AuthService {
|
|
16
|
+
#server: IRpdServer;
|
|
17
|
+
#jwtKey: string;
|
|
18
|
+
|
|
19
|
+
constructor(server: IRpdServer, jwtKey: string) {
|
|
20
|
+
this.#server = server;
|
|
21
|
+
this.#jwtKey = jwtKey;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
createUserAccessToken(options: CreateUserAccessTokenOptions): string {
|
|
25
|
+
const secretKey = Buffer.from(this.#jwtKey, "base64");
|
|
26
|
+
const token = createJwt(
|
|
27
|
+
{
|
|
28
|
+
iss: options.issuer,
|
|
29
|
+
sub: "userAccessToken",
|
|
30
|
+
aud: "" + options.userId,
|
|
31
|
+
iat: Math.floor(Date.now() / 1000),
|
|
32
|
+
act: options.userLogin,
|
|
33
|
+
} as UserAccessToken,
|
|
34
|
+
secretKey,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
return token;
|
|
38
|
+
}
|
|
39
|
+
}
|