@ruiapp/rapid-core 0.1.6 → 0.1.8
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/core/actionHandler.d.ts +1 -1
- package/dist/core/eventManager.d.ts +1 -1
- package/dist/core/pluginManager.d.ts +4 -1
- package/dist/core/request.d.ts +2 -1
- package/dist/core/routesBuilder.d.ts +2 -2
- package/dist/core/server.d.ts +16 -14
- package/dist/dataAccess/dataAccessor.d.ts +2 -2
- package/dist/dataAccess/entityManager.d.ts +2 -2
- package/dist/dataAccess/entityMapper.d.ts +1 -1
- package/dist/dataAccess/filterHelper.d.ts +1 -1
- package/dist/dataAccess/propertyMapper.d.ts +1 -1
- package/dist/helpers/runCollectionEntityActionHandler.d.ts +2 -2
- package/dist/index.d.ts +6 -6
- package/dist/index.js +278 -208
- package/dist/plugins/auth/{mod.d.ts → AuthPlugin.d.ts} +6 -4
- package/dist/plugins/auth/actionHandlers/createSession.d.ts +2 -2
- package/dist/plugins/auth/actionHandlers/deleteSession.d.ts +2 -2
- package/dist/plugins/auth/actionHandlers/getMyProfile.d.ts +2 -2
- package/dist/plugins/auth/models/AccessToken.d.ts +1 -1
- package/dist/plugins/auth/routes/index.d.ts +2 -2
- package/dist/plugins/dataManage/{mod.d.ts → DataManagePlugin.d.ts} +2 -2
- package/dist/plugins/dataManage/actionHandlers/addEntityRelations.d.ts +3 -3
- package/dist/plugins/dataManage/actionHandlers/countCollectionEntities.d.ts +3 -3
- package/dist/plugins/dataManage/actionHandlers/createCollectionEntitiesBatch.d.ts +3 -3
- package/dist/plugins/dataManage/actionHandlers/createCollectionEntity.d.ts +3 -3
- package/dist/plugins/dataManage/actionHandlers/deleteCollectionEntityById.d.ts +3 -3
- package/dist/plugins/dataManage/actionHandlers/findCollectionEntities.d.ts +3 -3
- package/dist/plugins/dataManage/actionHandlers/findCollectionEntityById.d.ts +3 -3
- package/dist/plugins/dataManage/actionHandlers/queryDatabase.d.ts +3 -3
- package/dist/plugins/dataManage/actionHandlers/removeEntityRelations.d.ts +3 -3
- package/dist/plugins/dataManage/actionHandlers/updateCollectionEntityById.d.ts +3 -3
- package/dist/plugins/fileManage/{mod.d.ts → FileManagePlugin.d.ts} +2 -2
- package/dist/plugins/fileManage/actionHandlers/downloadDocument.d.ts +2 -2
- package/dist/plugins/fileManage/actionHandlers/downloadFile.d.ts +2 -2
- package/dist/plugins/fileManage/actionHandlers/uploadFile.d.ts +2 -2
- package/dist/plugins/metaManage/{mod.d.ts → MetaManagePlugin.d.ts} +2 -2
- package/dist/plugins/metaManage/actionHandlers/getMetaModelDetail.d.ts +2 -2
- package/dist/plugins/metaManage/actionHandlers/listMetaModels.d.ts +2 -2
- package/dist/plugins/metaManage/actionHandlers/listMetaRoutes.d.ts +2 -2
- package/dist/plugins/routeManage/{mod.d.ts → RouteManagePlugin.d.ts} +2 -2
- package/dist/plugins/routeManage/actionHandlers/httpProxy.d.ts +3 -3
- package/dist/plugins/webhooks/{mod.d.ts → WebhooksPlugin.d.ts} +2 -2
- package/dist/proxy/mod.d.ts +1 -1
- package/dist/proxy/types.d.ts +2 -2
- package/dist/utilities/jwtUtility.d.ts +2 -2
- package/package.json +2 -2
- package/rollup.config.js +19 -2
- package/src/core/pluginManager.ts +13 -0
- package/src/core/request.ts +16 -3
- package/src/core/server.ts +15 -14
- package/src/index.ts +6 -6
- package/src/plugins/auth/{mod.ts → AuthPlugin.ts} +27 -2
- package/src/server.ts +1 -0
- package/src/utilities/jwtUtility.ts +3 -3
- /package/src/plugins/dataManage/{mod.ts → DataManagePlugin.ts} +0 -0
- /package/src/plugins/fileManage/{mod.ts → FileManagePlugin.ts} +0 -0
- /package/src/plugins/metaManage/{mod.ts → MetaManagePlugin.ts} +0 -0
- /package/src/plugins/routeManage/{mod.ts → RouteManagePlugin.ts} +0 -0
- /package/src/plugins/webhooks/{mod.ts → WebhooksPlugin.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -544,6 +544,14 @@ class PluginManager {
|
|
|
544
544
|
}
|
|
545
545
|
}
|
|
546
546
|
}
|
|
547
|
+
/** 在接收到HTTP请求,准备路由上下文时调用。 */
|
|
548
|
+
async onPrepareRouteContext(server, routeContext) {
|
|
549
|
+
for (const plugin of this.#plugins) {
|
|
550
|
+
if (plugin.onPrepareRouteContext) {
|
|
551
|
+
await plugin.onPrepareRouteContext(server, routeContext);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
547
555
|
}
|
|
548
556
|
|
|
549
557
|
class EventManager {
|
|
@@ -769,19 +777,255 @@ const convertToNewArray = (form, key, value) => {
|
|
|
769
777
|
form[key] = [form[key], value];
|
|
770
778
|
};
|
|
771
779
|
|
|
780
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
781
|
+
class AssertionError extends Error {
|
|
782
|
+
name = "AssertionError";
|
|
783
|
+
constructor(message) {
|
|
784
|
+
super(message);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
789
|
+
/** Make an assertion, error will be thrown if `expr` does not have truthy value. */
|
|
790
|
+
function assert(expr, msg = "") {
|
|
791
|
+
if (!expr) {
|
|
792
|
+
throw new AssertionError(msg);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
797
|
+
// This module is browser compatible.
|
|
798
|
+
/**
|
|
799
|
+
* Formats the given date to IMF date time format. (Reference:
|
|
800
|
+
* https://tools.ietf.org/html/rfc7231#section-7.1.1.1).
|
|
801
|
+
* IMF is the time format to use when generating times in HTTP
|
|
802
|
+
* headers. The time being formatted must be in UTC for Format to
|
|
803
|
+
* generate the correct format.
|
|
804
|
+
*
|
|
805
|
+
* @example
|
|
806
|
+
* ```ts
|
|
807
|
+
* import { toIMF } from "https://deno.land/std@$STD_VERSION/datetime/to_imf.ts";
|
|
808
|
+
*
|
|
809
|
+
* toIMF(new Date(0)); // => returns "Thu, 01 Jan 1970 00:00:00 GMT"
|
|
810
|
+
* ```
|
|
811
|
+
* @param date Date to parse
|
|
812
|
+
* @return IMF date formatted string
|
|
813
|
+
*/
|
|
814
|
+
function toIMF(date) {
|
|
815
|
+
function dtPad(v, lPad = 2) {
|
|
816
|
+
return v.padStart(lPad, "0");
|
|
817
|
+
}
|
|
818
|
+
const d = dtPad(date.getUTCDate().toString());
|
|
819
|
+
const h = dtPad(date.getUTCHours().toString());
|
|
820
|
+
const min = dtPad(date.getUTCMinutes().toString());
|
|
821
|
+
const s = dtPad(date.getUTCSeconds().toString());
|
|
822
|
+
const y = date.getUTCFullYear();
|
|
823
|
+
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
824
|
+
const months = [
|
|
825
|
+
"Jan",
|
|
826
|
+
"Feb",
|
|
827
|
+
"Mar",
|
|
828
|
+
"Apr",
|
|
829
|
+
"May",
|
|
830
|
+
"Jun",
|
|
831
|
+
"Jul",
|
|
832
|
+
"Aug",
|
|
833
|
+
"Sep",
|
|
834
|
+
"Oct",
|
|
835
|
+
"Nov",
|
|
836
|
+
"Dec",
|
|
837
|
+
];
|
|
838
|
+
return `${days[date.getUTCDay()]}, ${d} ${months[date.getUTCMonth()]} ${y} ${h}:${min}:${s} GMT`;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
842
|
+
const FIELD_CONTENT_REGEXP = /^(?=[\x20-\x7E]*$)[^()@<>,;:\\"\[\]?={}\s]+$/;
|
|
843
|
+
function toString(cookie) {
|
|
844
|
+
if (!cookie.name) {
|
|
845
|
+
return "";
|
|
846
|
+
}
|
|
847
|
+
const out = [];
|
|
848
|
+
validateName(cookie.name);
|
|
849
|
+
validateValue(cookie.name, cookie.value);
|
|
850
|
+
out.push(`${cookie.name}=${cookie.value}`);
|
|
851
|
+
// Fallback for invalid Set-Cookie
|
|
852
|
+
// ref: https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1
|
|
853
|
+
if (cookie.name.startsWith("__Secure")) {
|
|
854
|
+
cookie.secure = true;
|
|
855
|
+
}
|
|
856
|
+
if (cookie.name.startsWith("__Host")) {
|
|
857
|
+
cookie.path = "/";
|
|
858
|
+
cookie.secure = true;
|
|
859
|
+
delete cookie.domain;
|
|
860
|
+
}
|
|
861
|
+
if (cookie.secure) {
|
|
862
|
+
out.push("Secure");
|
|
863
|
+
}
|
|
864
|
+
if (cookie.httpOnly) {
|
|
865
|
+
out.push("HttpOnly");
|
|
866
|
+
}
|
|
867
|
+
if (typeof cookie.maxAge === "number" && Number.isInteger(cookie.maxAge)) {
|
|
868
|
+
assert(cookie.maxAge >= 0, "Max-Age must be an integer superior or equal to 0");
|
|
869
|
+
out.push(`Max-Age=${cookie.maxAge}`);
|
|
870
|
+
}
|
|
871
|
+
if (cookie.domain) {
|
|
872
|
+
validateDomain(cookie.domain);
|
|
873
|
+
out.push(`Domain=${cookie.domain}`);
|
|
874
|
+
}
|
|
875
|
+
if (cookie.sameSite) {
|
|
876
|
+
out.push(`SameSite=${cookie.sameSite}`);
|
|
877
|
+
}
|
|
878
|
+
if (cookie.path) {
|
|
879
|
+
validatePath(cookie.path);
|
|
880
|
+
out.push(`Path=${cookie.path}`);
|
|
881
|
+
}
|
|
882
|
+
if (cookie.expires) {
|
|
883
|
+
const { expires } = cookie;
|
|
884
|
+
const dateString = toIMF(typeof expires === "number" ? new Date(expires) : expires);
|
|
885
|
+
out.push(`Expires=${dateString}`);
|
|
886
|
+
}
|
|
887
|
+
if (cookie.unparsed) {
|
|
888
|
+
out.push(cookie.unparsed.join("; "));
|
|
889
|
+
}
|
|
890
|
+
return out.join("; ");
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Validate Cookie Name.
|
|
894
|
+
* @param name Cookie name.
|
|
895
|
+
*/
|
|
896
|
+
function validateName(name) {
|
|
897
|
+
if (name && !FIELD_CONTENT_REGEXP.test(name)) {
|
|
898
|
+
throw new TypeError(`Invalid cookie name: "${name}".`);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
/**
|
|
902
|
+
* Validate Path Value.
|
|
903
|
+
* See {@link https://tools.ietf.org/html/rfc6265#section-4.1.2.4}.
|
|
904
|
+
* @param path Path value.
|
|
905
|
+
*/
|
|
906
|
+
function validatePath(path) {
|
|
907
|
+
if (path == null) {
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
for (let i = 0; i < path.length; i++) {
|
|
911
|
+
const c = path.charAt(i);
|
|
912
|
+
if (c < String.fromCharCode(0x20) || c > String.fromCharCode(0x7E) || c == ";") {
|
|
913
|
+
throw new Error(path + ": Invalid cookie path char '" + c + "'");
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
}
|
|
917
|
+
/**
|
|
918
|
+
* Validate Cookie Value.
|
|
919
|
+
* See {@link https://tools.ietf.org/html/rfc6265#section-4.1}.
|
|
920
|
+
* @param value Cookie value.
|
|
921
|
+
*/
|
|
922
|
+
function validateValue(name, value) {
|
|
923
|
+
if (value == null || name == null)
|
|
924
|
+
return;
|
|
925
|
+
for (let i = 0; i < value.length; i++) {
|
|
926
|
+
const c = value.charAt(i);
|
|
927
|
+
if (c < String.fromCharCode(0x21) || c == String.fromCharCode(0x22) ||
|
|
928
|
+
c == String.fromCharCode(0x2c) || c == String.fromCharCode(0x3b) ||
|
|
929
|
+
c == String.fromCharCode(0x5c) || c == String.fromCharCode(0x7f)) {
|
|
930
|
+
throw new Error("RFC2616 cookie '" + name + "' cannot contain character '" + c + "'");
|
|
931
|
+
}
|
|
932
|
+
if (c > String.fromCharCode(0x80)) {
|
|
933
|
+
throw new Error("RFC2616 cookie '" + name + "' can only have US-ASCII chars as value" +
|
|
934
|
+
c.charCodeAt(0).toString(16));
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Validate Cookie Domain.
|
|
940
|
+
* See {@link https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.2.3}.
|
|
941
|
+
* @param domain Cookie domain.
|
|
942
|
+
*/
|
|
943
|
+
function validateDomain(domain) {
|
|
944
|
+
if (domain == null) {
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
const char1 = domain.charAt(0);
|
|
948
|
+
const charN = domain.charAt(domain.length - 1);
|
|
949
|
+
if (char1 == "-" || charN == "." || charN == "-") {
|
|
950
|
+
throw new Error("Invalid first/last char in cookie domain: " + domain);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Parse cookies of a header
|
|
955
|
+
*
|
|
956
|
+
* @example
|
|
957
|
+
* ```ts
|
|
958
|
+
* import { getCookies } from "https://deno.land/std@$STD_VERSION/http/cookie.ts";
|
|
959
|
+
*
|
|
960
|
+
* const headers = new Headers();
|
|
961
|
+
* headers.set("Cookie", "full=of; tasty=chocolate");
|
|
962
|
+
*
|
|
963
|
+
* const cookies = getCookies(headers);
|
|
964
|
+
* console.log(cookies); // { full: "of", tasty: "chocolate" }
|
|
965
|
+
* ```
|
|
966
|
+
*
|
|
967
|
+
* @param headers The headers instance to get cookies from
|
|
968
|
+
* @return Object with cookie names as keys
|
|
969
|
+
*/
|
|
970
|
+
function getCookies(headers) {
|
|
971
|
+
const cookie = headers.get("Cookie");
|
|
972
|
+
if (cookie != null) {
|
|
973
|
+
const out = {};
|
|
974
|
+
const c = cookie.split(";");
|
|
975
|
+
for (const kv of c) {
|
|
976
|
+
const [cookieKey, ...cookieVal] = kv.split("=");
|
|
977
|
+
assert(cookieKey != null);
|
|
978
|
+
const key = cookieKey.trim();
|
|
979
|
+
out[key] = cookieVal.join("=");
|
|
980
|
+
}
|
|
981
|
+
return out;
|
|
982
|
+
}
|
|
983
|
+
return {};
|
|
984
|
+
}
|
|
985
|
+
/**
|
|
986
|
+
* Set the cookie header properly in the headers
|
|
987
|
+
*
|
|
988
|
+
* @example
|
|
989
|
+
* ```ts
|
|
990
|
+
* import {
|
|
991
|
+
* Cookie,
|
|
992
|
+
* setCookie,
|
|
993
|
+
* } from "https://deno.land/std@$STD_VERSION/http/cookie.ts";
|
|
994
|
+
*
|
|
995
|
+
* const headers = new Headers();
|
|
996
|
+
* const cookie: Cookie = { name: "Space", value: "Cat" };
|
|
997
|
+
* setCookie(headers, cookie);
|
|
998
|
+
*
|
|
999
|
+
* const cookieHeader = headers.get("set-cookie");
|
|
1000
|
+
* console.log(cookieHeader); // Space=Cat
|
|
1001
|
+
* ```
|
|
1002
|
+
*
|
|
1003
|
+
* @param headers The headers instance to set the cookie to
|
|
1004
|
+
* @param cookie Cookie to set
|
|
1005
|
+
*/
|
|
1006
|
+
function setCookie(headers, cookie) {
|
|
1007
|
+
// Parsing cookie headers to make consistent set-cookie header
|
|
1008
|
+
// ref: https://tools.ietf.org/html/rfc6265#section-4.1.1
|
|
1009
|
+
const v = toString(cookie);
|
|
1010
|
+
if (v) {
|
|
1011
|
+
headers.append("Set-Cookie", v);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
|
|
772
1015
|
const GlobalRequest = global.Request;
|
|
773
1016
|
class RapidRequest {
|
|
774
1017
|
#raw;
|
|
775
1018
|
#bodyParsed;
|
|
776
1019
|
#body;
|
|
1020
|
+
#headers;
|
|
1021
|
+
#parsedCookies;
|
|
777
1022
|
method;
|
|
778
1023
|
url;
|
|
779
|
-
headers;
|
|
780
1024
|
constructor(req) {
|
|
781
1025
|
this.#raw = req;
|
|
782
1026
|
this.method = req.method;
|
|
783
1027
|
this.url = new URL(req.url);
|
|
784
|
-
this
|
|
1028
|
+
this.#headers = req.headers;
|
|
785
1029
|
}
|
|
786
1030
|
async parseBody() {
|
|
787
1031
|
if (this.#bodyParsed) {
|
|
@@ -791,7 +1035,7 @@ class RapidRequest {
|
|
|
791
1035
|
const requestMethod = this.method;
|
|
792
1036
|
if (requestMethod === "POST" || requestMethod === "PUT" || requestMethod === "PATCH") {
|
|
793
1037
|
const req = this.#raw;
|
|
794
|
-
const contentType = this
|
|
1038
|
+
const contentType = this.#headers.get("Content-Type");
|
|
795
1039
|
if (contentType.includes("json")) {
|
|
796
1040
|
this.#body = {
|
|
797
1041
|
type: "json",
|
|
@@ -820,6 +1064,15 @@ class RapidRequest {
|
|
|
820
1064
|
get rawRequest() {
|
|
821
1065
|
return this.#raw;
|
|
822
1066
|
}
|
|
1067
|
+
get headers() {
|
|
1068
|
+
return this.#headers;
|
|
1069
|
+
}
|
|
1070
|
+
get cookies() {
|
|
1071
|
+
if (!this.#parsedCookies) {
|
|
1072
|
+
this.#parsedCookies = getCookies(this.#headers);
|
|
1073
|
+
}
|
|
1074
|
+
return this.#parsedCookies;
|
|
1075
|
+
}
|
|
823
1076
|
get body() {
|
|
824
1077
|
if (!this.#bodyParsed) {
|
|
825
1078
|
throw new Error("Request body not parsed, you should call 'parseBody()' method before getting the body.");
|
|
@@ -3450,209 +3703,6 @@ class WebhooksPlugin {
|
|
|
3450
3703
|
}
|
|
3451
3704
|
}
|
|
3452
3705
|
|
|
3453
|
-
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
3454
|
-
class AssertionError extends Error {
|
|
3455
|
-
name = "AssertionError";
|
|
3456
|
-
constructor(message) {
|
|
3457
|
-
super(message);
|
|
3458
|
-
}
|
|
3459
|
-
}
|
|
3460
|
-
|
|
3461
|
-
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
3462
|
-
/** Make an assertion, error will be thrown if `expr` does not have truthy value. */
|
|
3463
|
-
function assert(expr, msg = "") {
|
|
3464
|
-
if (!expr) {
|
|
3465
|
-
throw new AssertionError(msg);
|
|
3466
|
-
}
|
|
3467
|
-
}
|
|
3468
|
-
|
|
3469
|
-
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
3470
|
-
// This module is browser compatible.
|
|
3471
|
-
/**
|
|
3472
|
-
* Formats the given date to IMF date time format. (Reference:
|
|
3473
|
-
* https://tools.ietf.org/html/rfc7231#section-7.1.1.1).
|
|
3474
|
-
* IMF is the time format to use when generating times in HTTP
|
|
3475
|
-
* headers. The time being formatted must be in UTC for Format to
|
|
3476
|
-
* generate the correct format.
|
|
3477
|
-
*
|
|
3478
|
-
* @example
|
|
3479
|
-
* ```ts
|
|
3480
|
-
* import { toIMF } from "https://deno.land/std@$STD_VERSION/datetime/to_imf.ts";
|
|
3481
|
-
*
|
|
3482
|
-
* toIMF(new Date(0)); // => returns "Thu, 01 Jan 1970 00:00:00 GMT"
|
|
3483
|
-
* ```
|
|
3484
|
-
* @param date Date to parse
|
|
3485
|
-
* @return IMF date formatted string
|
|
3486
|
-
*/
|
|
3487
|
-
function toIMF(date) {
|
|
3488
|
-
function dtPad(v, lPad = 2) {
|
|
3489
|
-
return v.padStart(lPad, "0");
|
|
3490
|
-
}
|
|
3491
|
-
const d = dtPad(date.getUTCDate().toString());
|
|
3492
|
-
const h = dtPad(date.getUTCHours().toString());
|
|
3493
|
-
const min = dtPad(date.getUTCMinutes().toString());
|
|
3494
|
-
const s = dtPad(date.getUTCSeconds().toString());
|
|
3495
|
-
const y = date.getUTCFullYear();
|
|
3496
|
-
const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|
3497
|
-
const months = [
|
|
3498
|
-
"Jan",
|
|
3499
|
-
"Feb",
|
|
3500
|
-
"Mar",
|
|
3501
|
-
"Apr",
|
|
3502
|
-
"May",
|
|
3503
|
-
"Jun",
|
|
3504
|
-
"Jul",
|
|
3505
|
-
"Aug",
|
|
3506
|
-
"Sep",
|
|
3507
|
-
"Oct",
|
|
3508
|
-
"Nov",
|
|
3509
|
-
"Dec",
|
|
3510
|
-
];
|
|
3511
|
-
return `${days[date.getUTCDay()]}, ${d} ${months[date.getUTCMonth()]} ${y} ${h}:${min}:${s} GMT`;
|
|
3512
|
-
}
|
|
3513
|
-
|
|
3514
|
-
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
|
3515
|
-
const FIELD_CONTENT_REGEXP = /^(?=[\x20-\x7E]*$)[^()@<>,;:\\"\[\]?={}\s]+$/;
|
|
3516
|
-
function toString(cookie) {
|
|
3517
|
-
if (!cookie.name) {
|
|
3518
|
-
return "";
|
|
3519
|
-
}
|
|
3520
|
-
const out = [];
|
|
3521
|
-
validateName(cookie.name);
|
|
3522
|
-
validateValue(cookie.name, cookie.value);
|
|
3523
|
-
out.push(`${cookie.name}=${cookie.value}`);
|
|
3524
|
-
// Fallback for invalid Set-Cookie
|
|
3525
|
-
// ref: https://tools.ietf.org/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1
|
|
3526
|
-
if (cookie.name.startsWith("__Secure")) {
|
|
3527
|
-
cookie.secure = true;
|
|
3528
|
-
}
|
|
3529
|
-
if (cookie.name.startsWith("__Host")) {
|
|
3530
|
-
cookie.path = "/";
|
|
3531
|
-
cookie.secure = true;
|
|
3532
|
-
delete cookie.domain;
|
|
3533
|
-
}
|
|
3534
|
-
if (cookie.secure) {
|
|
3535
|
-
out.push("Secure");
|
|
3536
|
-
}
|
|
3537
|
-
if (cookie.httpOnly) {
|
|
3538
|
-
out.push("HttpOnly");
|
|
3539
|
-
}
|
|
3540
|
-
if (typeof cookie.maxAge === "number" && Number.isInteger(cookie.maxAge)) {
|
|
3541
|
-
assert(cookie.maxAge >= 0, "Max-Age must be an integer superior or equal to 0");
|
|
3542
|
-
out.push(`Max-Age=${cookie.maxAge}`);
|
|
3543
|
-
}
|
|
3544
|
-
if (cookie.domain) {
|
|
3545
|
-
validateDomain(cookie.domain);
|
|
3546
|
-
out.push(`Domain=${cookie.domain}`);
|
|
3547
|
-
}
|
|
3548
|
-
if (cookie.sameSite) {
|
|
3549
|
-
out.push(`SameSite=${cookie.sameSite}`);
|
|
3550
|
-
}
|
|
3551
|
-
if (cookie.path) {
|
|
3552
|
-
validatePath(cookie.path);
|
|
3553
|
-
out.push(`Path=${cookie.path}`);
|
|
3554
|
-
}
|
|
3555
|
-
if (cookie.expires) {
|
|
3556
|
-
const { expires } = cookie;
|
|
3557
|
-
const dateString = toIMF(typeof expires === "number" ? new Date(expires) : expires);
|
|
3558
|
-
out.push(`Expires=${dateString}`);
|
|
3559
|
-
}
|
|
3560
|
-
if (cookie.unparsed) {
|
|
3561
|
-
out.push(cookie.unparsed.join("; "));
|
|
3562
|
-
}
|
|
3563
|
-
return out.join("; ");
|
|
3564
|
-
}
|
|
3565
|
-
/**
|
|
3566
|
-
* Validate Cookie Name.
|
|
3567
|
-
* @param name Cookie name.
|
|
3568
|
-
*/
|
|
3569
|
-
function validateName(name) {
|
|
3570
|
-
if (name && !FIELD_CONTENT_REGEXP.test(name)) {
|
|
3571
|
-
throw new TypeError(`Invalid cookie name: "${name}".`);
|
|
3572
|
-
}
|
|
3573
|
-
}
|
|
3574
|
-
/**
|
|
3575
|
-
* Validate Path Value.
|
|
3576
|
-
* See {@link https://tools.ietf.org/html/rfc6265#section-4.1.2.4}.
|
|
3577
|
-
* @param path Path value.
|
|
3578
|
-
*/
|
|
3579
|
-
function validatePath(path) {
|
|
3580
|
-
if (path == null) {
|
|
3581
|
-
return;
|
|
3582
|
-
}
|
|
3583
|
-
for (let i = 0; i < path.length; i++) {
|
|
3584
|
-
const c = path.charAt(i);
|
|
3585
|
-
if (c < String.fromCharCode(0x20) || c > String.fromCharCode(0x7E) || c == ";") {
|
|
3586
|
-
throw new Error(path + ": Invalid cookie path char '" + c + "'");
|
|
3587
|
-
}
|
|
3588
|
-
}
|
|
3589
|
-
}
|
|
3590
|
-
/**
|
|
3591
|
-
* Validate Cookie Value.
|
|
3592
|
-
* See {@link https://tools.ietf.org/html/rfc6265#section-4.1}.
|
|
3593
|
-
* @param value Cookie value.
|
|
3594
|
-
*/
|
|
3595
|
-
function validateValue(name, value) {
|
|
3596
|
-
if (value == null || name == null)
|
|
3597
|
-
return;
|
|
3598
|
-
for (let i = 0; i < value.length; i++) {
|
|
3599
|
-
const c = value.charAt(i);
|
|
3600
|
-
if (c < String.fromCharCode(0x21) || c == String.fromCharCode(0x22) ||
|
|
3601
|
-
c == String.fromCharCode(0x2c) || c == String.fromCharCode(0x3b) ||
|
|
3602
|
-
c == String.fromCharCode(0x5c) || c == String.fromCharCode(0x7f)) {
|
|
3603
|
-
throw new Error("RFC2616 cookie '" + name + "' cannot contain character '" + c + "'");
|
|
3604
|
-
}
|
|
3605
|
-
if (c > String.fromCharCode(0x80)) {
|
|
3606
|
-
throw new Error("RFC2616 cookie '" + name + "' can only have US-ASCII chars as value" +
|
|
3607
|
-
c.charCodeAt(0).toString(16));
|
|
3608
|
-
}
|
|
3609
|
-
}
|
|
3610
|
-
}
|
|
3611
|
-
/**
|
|
3612
|
-
* Validate Cookie Domain.
|
|
3613
|
-
* See {@link https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.2.3}.
|
|
3614
|
-
* @param domain Cookie domain.
|
|
3615
|
-
*/
|
|
3616
|
-
function validateDomain(domain) {
|
|
3617
|
-
if (domain == null) {
|
|
3618
|
-
return;
|
|
3619
|
-
}
|
|
3620
|
-
const char1 = domain.charAt(0);
|
|
3621
|
-
const charN = domain.charAt(domain.length - 1);
|
|
3622
|
-
if (char1 == "-" || charN == "." || charN == "-") {
|
|
3623
|
-
throw new Error("Invalid first/last char in cookie domain: " + domain);
|
|
3624
|
-
}
|
|
3625
|
-
}
|
|
3626
|
-
/**
|
|
3627
|
-
* Set the cookie header properly in the headers
|
|
3628
|
-
*
|
|
3629
|
-
* @example
|
|
3630
|
-
* ```ts
|
|
3631
|
-
* import {
|
|
3632
|
-
* Cookie,
|
|
3633
|
-
* setCookie,
|
|
3634
|
-
* } from "https://deno.land/std@$STD_VERSION/http/cookie.ts";
|
|
3635
|
-
*
|
|
3636
|
-
* const headers = new Headers();
|
|
3637
|
-
* const cookie: Cookie = { name: "Space", value: "Cat" };
|
|
3638
|
-
* setCookie(headers, cookie);
|
|
3639
|
-
*
|
|
3640
|
-
* const cookieHeader = headers.get("set-cookie");
|
|
3641
|
-
* console.log(cookieHeader); // Space=Cat
|
|
3642
|
-
* ```
|
|
3643
|
-
*
|
|
3644
|
-
* @param headers The headers instance to set the cookie to
|
|
3645
|
-
* @param cookie Cookie to set
|
|
3646
|
-
*/
|
|
3647
|
-
function setCookie(headers, cookie) {
|
|
3648
|
-
// Parsing cookie headers to make consistent set-cookie header
|
|
3649
|
-
// ref: https://tools.ietf.org/html/rfc6265#section-4.1.1
|
|
3650
|
-
const v = toString(cookie);
|
|
3651
|
-
if (v) {
|
|
3652
|
-
headers.append("Set-Cookie", v);
|
|
3653
|
-
}
|
|
3654
|
-
}
|
|
3655
|
-
|
|
3656
3706
|
const code$5 = "createSession";
|
|
3657
3707
|
async function handler$5(plugin, ctx, options) {
|
|
3658
3708
|
const { server, input, routerContext } = ctx;
|
|
@@ -3868,7 +3918,7 @@ var pluginRoutes = [
|
|
|
3868
3918
|
/**
|
|
3869
3919
|
* Auth manager plugin
|
|
3870
3920
|
*/
|
|
3871
|
-
class
|
|
3921
|
+
class AuthPlugin {
|
|
3872
3922
|
get code() {
|
|
3873
3923
|
return "authManager";
|
|
3874
3924
|
}
|
|
@@ -3914,6 +3964,26 @@ class AuthManager {
|
|
|
3914
3964
|
}
|
|
3915
3965
|
async onApplicationReady(server, applicationConfig) {
|
|
3916
3966
|
}
|
|
3967
|
+
async onPrepareRouteContext(server, routeContext) {
|
|
3968
|
+
const request = routeContext.request;
|
|
3969
|
+
let token;
|
|
3970
|
+
const headers = request.headers;
|
|
3971
|
+
// No Authorization header
|
|
3972
|
+
if (headers.has("Authorization")) {
|
|
3973
|
+
// Authorization header has no Bearer or no token
|
|
3974
|
+
const authHeader = headers.get("Authorization");
|
|
3975
|
+
if (!authHeader.startsWith("Bearer ") || authHeader.length <= 7) {
|
|
3976
|
+
throw new Error('AUTHORIZATION_HEADER_INVALID');
|
|
3977
|
+
}
|
|
3978
|
+
token = authHeader.slice(7);
|
|
3979
|
+
}
|
|
3980
|
+
else {
|
|
3981
|
+
token = request.cookies[server.config.sessionCookieName];
|
|
3982
|
+
}
|
|
3983
|
+
const tokenPayload = verifyJwt(token, server.config.jwtKey);
|
|
3984
|
+
routeContext.state.userId = tokenPayload.aud;
|
|
3985
|
+
routeContext.state.userLogin = tokenPayload.act;
|
|
3986
|
+
}
|
|
3917
3987
|
}
|
|
3918
3988
|
|
|
3919
3989
|
async function readFile(path) {
|
|
@@ -4076,7 +4146,7 @@ class FileManager {
|
|
|
4076
4146
|
|
|
4077
4147
|
fixBigIntJSONSerialize();
|
|
4078
4148
|
|
|
4079
|
-
exports.AuthPlugin =
|
|
4149
|
+
exports.AuthPlugin = AuthPlugin;
|
|
4080
4150
|
exports.DataManagePlugin = DataManager;
|
|
4081
4151
|
exports.FileManagePlugin = FileManager;
|
|
4082
4152
|
exports.GlobalRequest = GlobalRequest;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Auth manager plugin
|
|
3
3
|
*/
|
|
4
|
-
import { RpdApplicationConfig } from "
|
|
5
|
-
import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "
|
|
6
|
-
|
|
4
|
+
import { RpdApplicationConfig } from "../../types";
|
|
5
|
+
import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "../../core/server";
|
|
6
|
+
import { RouteContext } from "../../core/routeContext";
|
|
7
|
+
declare class AuthPlugin implements RapidPlugin {
|
|
7
8
|
get code(): string;
|
|
8
9
|
get description(): string;
|
|
9
10
|
get extendingAbilities(): RpdServerPluginExtendingAbilities[];
|
|
@@ -21,5 +22,6 @@ declare class AuthManager implements RapidPlugin {
|
|
|
21
22
|
configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
|
|
22
23
|
onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
|
|
23
24
|
onApplicationReady(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
|
|
25
|
+
onPrepareRouteContext(server: IRpdServer, routeContext: RouteContext): Promise<void>;
|
|
24
26
|
}
|
|
25
|
-
export default
|
|
27
|
+
export default AuthPlugin;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ActionHandlerContext } from "
|
|
2
|
-
import { RapidPlugin } from "
|
|
1
|
+
import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
2
|
+
import { RapidPlugin } from "../../../core/server";
|
|
3
3
|
export interface UserAccessToken {
|
|
4
4
|
sub: "userAccessToken";
|
|
5
5
|
aud: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionHandlerContext } from "
|
|
2
|
-
import { RapidPlugin } from "
|
|
1
|
+
import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
2
|
+
import { RapidPlugin } from "../../../core/server";
|
|
3
3
|
export declare const code = "deleteSession";
|
|
4
4
|
export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: any): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionHandlerContext } from "
|
|
2
|
-
import { RapidPlugin } from "
|
|
1
|
+
import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
2
|
+
import { RapidPlugin } from "../../../core/server";
|
|
3
3
|
export declare const code = "getMyProfile";
|
|
4
4
|
export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: any): Promise<void>;
|
|
@@ -5,7 +5,7 @@ declare const _default: ({
|
|
|
5
5
|
type: "RESTful";
|
|
6
6
|
method: "GET";
|
|
7
7
|
endpoint: string;
|
|
8
|
-
|
|
8
|
+
actions: {
|
|
9
9
|
code: string;
|
|
10
10
|
}[];
|
|
11
11
|
} | {
|
|
@@ -15,7 +15,7 @@ declare const _default: ({
|
|
|
15
15
|
type: "RESTful";
|
|
16
16
|
method: "POST";
|
|
17
17
|
endpoint: string;
|
|
18
|
-
|
|
18
|
+
actions: {
|
|
19
19
|
code: string;
|
|
20
20
|
}[];
|
|
21
21
|
})[];
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* This plugin provide:
|
|
4
4
|
* - routes for manage data in database.
|
|
5
5
|
*/
|
|
6
|
-
import { RpdApplicationConfig } from "
|
|
7
|
-
import { RpdServerPluginExtendingAbilities, RpdServerPluginConfigurableTargetOptions, RpdConfigurationItemOptions, IRpdServer, RapidPlugin } from "
|
|
6
|
+
import { RpdApplicationConfig } from "../../types";
|
|
7
|
+
import { RpdServerPluginExtendingAbilities, RpdServerPluginConfigurableTargetOptions, RpdConfigurationItemOptions, IRpdServer, RapidPlugin } from "../../core/server";
|
|
8
8
|
declare class DataManager implements RapidPlugin {
|
|
9
9
|
get code(): string;
|
|
10
10
|
get description(): string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RunEntityActionHandlerOptions } from "
|
|
2
|
-
import { ActionHandlerContext } from "
|
|
3
|
-
import { RapidPlugin } from "
|
|
1
|
+
import { RunEntityActionHandlerOptions } from "../../../types";
|
|
2
|
+
import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
3
|
+
import { RapidPlugin } from "../../../core/server";
|
|
4
4
|
export declare const code = "addEntityRelations";
|
|
5
5
|
export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: RunEntityActionHandlerOptions): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RunEntityActionHandlerOptions } from "
|
|
2
|
-
import { ActionHandlerContext } from "
|
|
3
|
-
import { RapidPlugin } from "
|
|
1
|
+
import { RunEntityActionHandlerOptions } from "../../../types";
|
|
2
|
+
import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
3
|
+
import { RapidPlugin } from "../../../core/server";
|
|
4
4
|
export declare const code = "countCollectionEntities";
|
|
5
5
|
export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: RunEntityActionHandlerOptions): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RunEntityActionHandlerOptions } from "
|
|
2
|
-
import { ActionHandlerContext } from "
|
|
3
|
-
import { RapidPlugin } from "
|
|
1
|
+
import { RunEntityActionHandlerOptions } from "../../../types";
|
|
2
|
+
import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
3
|
+
import { RapidPlugin } from "../../../core/server";
|
|
4
4
|
export declare const code = "createCollectionEntitiesBatch";
|
|
5
5
|
export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: RunEntityActionHandlerOptions): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RunEntityActionHandlerOptions } from "
|
|
2
|
-
import { ActionHandlerContext } from "
|
|
3
|
-
import { RapidPlugin } from "
|
|
1
|
+
import { RunEntityActionHandlerOptions } from "../../../types";
|
|
2
|
+
import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
3
|
+
import { RapidPlugin } from "../../../core/server";
|
|
4
4
|
export declare const code = "createCollectionEntity";
|
|
5
5
|
export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: RunEntityActionHandlerOptions): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { RunEntityActionHandlerOptions } from "
|
|
2
|
-
import { ActionHandlerContext } from "
|
|
3
|
-
import { RapidPlugin } from "
|
|
1
|
+
import { RunEntityActionHandlerOptions } from "../../../types";
|
|
2
|
+
import { ActionHandlerContext } from "../../../core/actionHandler";
|
|
3
|
+
import { RapidPlugin } from "../../../core/server";
|
|
4
4
|
export declare const code = "deleteCollectionEntityById";
|
|
5
5
|
export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: RunEntityActionHandlerOptions): Promise<void>;
|