@terreno/api 0.9.3 → 0.11.0
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/bunfig.toml +5 -2
- package/bunfig.unit.toml +3 -0
- package/dist/auth.test.js +257 -0
- package/dist/consentApp.test.js +245 -0
- package/dist/expressServer.js +3 -9
- package/dist/expressServer.test.js +4 -7
- package/dist/githubAuth.test.js +380 -0
- package/dist/logger.test.d.ts +1 -0
- package/dist/logger.test.js +143 -0
- package/dist/notifiers/googleChatNotifier.test.js +37 -0
- package/dist/openApi.js +2 -2
- package/dist/openApi.test.js +125 -0
- package/dist/openApiBuilder.d.ts +1 -0
- package/dist/openApiBuilder.js +13 -2
- package/dist/openApiBuilder.test.js +66 -0
- package/dist/openApiEtag.test.js +8 -0
- package/dist/openApiValidator.test.js +309 -0
- package/dist/permissions.middleware.test.d.ts +1 -0
- package/dist/permissions.middleware.test.js +341 -0
- package/dist/plugins.d.ts +8 -8
- package/dist/plugins.js +38 -32
- package/dist/populate.test.js +99 -0
- package/dist/syncConsents.js +2 -2
- package/dist/syncConsents.test.js +273 -0
- package/dist/tests/bunSetup.js +27 -22
- package/dist/tests.d.ts +3 -3
- package/dist/tests.js +78 -82
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +7 -7
- package/package.json +2 -1
- package/src/__snapshots__/openApi.test.ts.snap +48 -0
- package/src/auth.test.ts +147 -0
- package/src/consentApp.test.ts +162 -0
- package/src/expressServer.test.ts +4 -11
- package/src/expressServer.ts +4 -8
- package/src/githubAuth.test.ts +307 -1
- package/src/logger.test.ts +149 -0
- package/src/notifiers/googleChatNotifier.test.ts +24 -0
- package/src/openApi.test.ts +157 -1
- package/src/openApi.ts +6 -2
- package/src/openApiBuilder.test.ts +81 -0
- package/src/openApiBuilder.ts +17 -2
- package/src/openApiEtag.test.ts +11 -0
- package/src/openApiValidator.test.ts +410 -0
- package/src/permissions.middleware.test.ts +197 -0
- package/src/plugins.ts +32 -23
- package/src/populate.test.ts +78 -2
- package/src/syncConsents.test.ts +145 -0
- package/src/syncConsents.ts +1 -1
- package/src/tests/bunSetup.ts +14 -8
- package/src/tests.ts +8 -8
- package/src/utils.ts +4 -4
package/bunfig.toml
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
preload = ["./src/tests/bunSetup.ts"]
|
|
3
3
|
root = "./src"
|
|
4
4
|
coverage = true
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
coveragePathIgnorePatterns = ["dist/**", "**/*.test.ts", "**/tests/**", "**/vendor/**", "../**"]
|
|
6
|
+
# Enforced by scripts/check-coverage.ts; Bun parses this key but does not
|
|
7
|
+
# fail the run when coverage is below threshold. See
|
|
8
|
+
# https://github.com/oven-sh/bun/issues/7367 and https://github.com/oven-sh/bun/pull/27933.
|
|
9
|
+
coverageThreshold = { line = 95, function = 95 }
|
|
7
10
|
|
package/bunfig.unit.toml
ADDED
package/dist/auth.test.js
CHANGED
|
@@ -910,4 +910,261 @@ var utils_1 = require("./utils");
|
|
|
910
910
|
}
|
|
911
911
|
});
|
|
912
912
|
}); });
|
|
913
|
+
(0, bun_test_1.it)("throws when TOKEN_SECRET is not set", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
914
|
+
var caught, error_1;
|
|
915
|
+
return __generator(this, function (_a) {
|
|
916
|
+
switch (_a.label) {
|
|
917
|
+
case 0:
|
|
918
|
+
process.env.TOKEN_SECRET = "";
|
|
919
|
+
_a.label = 1;
|
|
920
|
+
case 1:
|
|
921
|
+
_a.trys.push([1, 3, , 4]);
|
|
922
|
+
return [4 /*yield*/, (0, auth_1.generateTokens)({ _id: "user-123" })];
|
|
923
|
+
case 2:
|
|
924
|
+
_a.sent();
|
|
925
|
+
return [3 /*break*/, 4];
|
|
926
|
+
case 3:
|
|
927
|
+
error_1 = _a.sent();
|
|
928
|
+
caught = error_1;
|
|
929
|
+
return [3 /*break*/, 4];
|
|
930
|
+
case 4:
|
|
931
|
+
(0, bun_test_1.expect)(caught).toBeDefined();
|
|
932
|
+
(0, bun_test_1.expect)(caught.message).toBe("TOKEN_SECRET must be set in env.");
|
|
933
|
+
return [2 /*return*/];
|
|
934
|
+
}
|
|
935
|
+
});
|
|
936
|
+
}); });
|
|
937
|
+
(0, bun_test_1.it)("uses TOKEN_EXPIRES_IN from env when valid", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
938
|
+
var jwtLib, result, decoded, expectedExp;
|
|
939
|
+
return __generator(this, function (_a) {
|
|
940
|
+
switch (_a.label) {
|
|
941
|
+
case 0: return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require("jsonwebtoken")); })];
|
|
942
|
+
case 1:
|
|
943
|
+
jwtLib = _a.sent();
|
|
944
|
+
process.env.TOKEN_EXPIRES_IN = "2h";
|
|
945
|
+
return [4 /*yield*/, (0, auth_1.generateTokens)({ _id: "user-123" })];
|
|
946
|
+
case 2:
|
|
947
|
+
result = _a.sent();
|
|
948
|
+
decoded = jwtLib.decode(result.token);
|
|
949
|
+
expectedExp = Math.floor(Date.now() / 1000) + 2 * 3600;
|
|
950
|
+
(0, bun_test_1.expect)(decoded.exp).toBeGreaterThan(expectedExp - 10);
|
|
951
|
+
(0, bun_test_1.expect)(decoded.exp).toBeLessThan(expectedExp + 10);
|
|
952
|
+
return [2 /*return*/];
|
|
953
|
+
}
|
|
954
|
+
});
|
|
955
|
+
}); });
|
|
956
|
+
(0, bun_test_1.it)("uses REFRESH_TOKEN_EXPIRES_IN from env when valid", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
957
|
+
var jwtLib, result, decoded, expectedExp;
|
|
958
|
+
return __generator(this, function (_a) {
|
|
959
|
+
switch (_a.label) {
|
|
960
|
+
case 0: return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require("jsonwebtoken")); })];
|
|
961
|
+
case 1:
|
|
962
|
+
jwtLib = _a.sent();
|
|
963
|
+
process.env.REFRESH_TOKEN_EXPIRES_IN = "1h";
|
|
964
|
+
return [4 /*yield*/, (0, auth_1.generateTokens)({ _id: "user-123" })];
|
|
965
|
+
case 2:
|
|
966
|
+
result = _a.sent();
|
|
967
|
+
decoded = jwtLib.decode(result.refreshToken);
|
|
968
|
+
expectedExp = Math.floor(Date.now() / 1000) + 3600;
|
|
969
|
+
(0, bun_test_1.expect)(decoded.exp).toBeGreaterThan(expectedExp - 10);
|
|
970
|
+
(0, bun_test_1.expect)(decoded.exp).toBeLessThan(expectedExp + 10);
|
|
971
|
+
return [2 /*return*/];
|
|
972
|
+
}
|
|
973
|
+
});
|
|
974
|
+
}); });
|
|
975
|
+
(0, bun_test_1.it)("does not issue refresh token when REFRESH_TOKEN_SECRET is not set", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
976
|
+
var result;
|
|
977
|
+
return __generator(this, function (_a) {
|
|
978
|
+
switch (_a.label) {
|
|
979
|
+
case 0:
|
|
980
|
+
process.env.REFRESH_TOKEN_SECRET = "";
|
|
981
|
+
return [4 /*yield*/, (0, auth_1.generateTokens)({ _id: "user-123" })];
|
|
982
|
+
case 1:
|
|
983
|
+
result = _a.sent();
|
|
984
|
+
(0, bun_test_1.expect)(result.token).toBeDefined();
|
|
985
|
+
(0, bun_test_1.expect)(result.refreshToken).toBeUndefined();
|
|
986
|
+
return [2 /*return*/];
|
|
987
|
+
}
|
|
988
|
+
});
|
|
989
|
+
}); });
|
|
990
|
+
});
|
|
991
|
+
(0, bun_test_1.describe)("addAuthRoutes /refresh_token error paths", function () {
|
|
992
|
+
var app;
|
|
993
|
+
var agent;
|
|
994
|
+
(0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
995
|
+
return __generator(this, function (_a) {
|
|
996
|
+
switch (_a.label) {
|
|
997
|
+
case 0:
|
|
998
|
+
(0, bun_test_1.setSystemTime)();
|
|
999
|
+
return [4 /*yield*/, (0, tests_1.setupDb)()];
|
|
1000
|
+
case 1:
|
|
1001
|
+
_a.sent();
|
|
1002
|
+
app = (0, expressServer_1.setupServer)({
|
|
1003
|
+
addRoutes: function () { },
|
|
1004
|
+
skipListen: true,
|
|
1005
|
+
userModel: tests_1.UserModel,
|
|
1006
|
+
});
|
|
1007
|
+
agent = supertest_1.default.agent(app);
|
|
1008
|
+
return [2 /*return*/];
|
|
1009
|
+
}
|
|
1010
|
+
});
|
|
1011
|
+
}); });
|
|
1012
|
+
(0, bun_test_1.afterEach)(function () {
|
|
1013
|
+
(0, bun_test_1.setSystemTime)();
|
|
1014
|
+
});
|
|
1015
|
+
(0, bun_test_1.it)("returns 401 when no refreshToken in body", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1016
|
+
var res;
|
|
1017
|
+
return __generator(this, function (_a) {
|
|
1018
|
+
switch (_a.label) {
|
|
1019
|
+
case 0: return [4 /*yield*/, agent.post("/auth/refresh_token").send({}).expect(401)];
|
|
1020
|
+
case 1:
|
|
1021
|
+
res = _a.sent();
|
|
1022
|
+
(0, bun_test_1.expect)(res.body.message).toContain("No refresh token provided");
|
|
1023
|
+
return [2 /*return*/];
|
|
1024
|
+
}
|
|
1025
|
+
});
|
|
1026
|
+
}); });
|
|
1027
|
+
(0, bun_test_1.it)("returns 401 when refresh token is invalid", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1028
|
+
var res;
|
|
1029
|
+
return __generator(this, function (_a) {
|
|
1030
|
+
switch (_a.label) {
|
|
1031
|
+
case 0: return [4 /*yield*/, agent
|
|
1032
|
+
.post("/auth/refresh_token")
|
|
1033
|
+
.send({ refreshToken: "not-a-valid-jwt" })
|
|
1034
|
+
.expect(401)];
|
|
1035
|
+
case 1:
|
|
1036
|
+
res = _a.sent();
|
|
1037
|
+
(0, bun_test_1.expect)(res.body.message).toBeDefined();
|
|
1038
|
+
return [2 /*return*/];
|
|
1039
|
+
}
|
|
1040
|
+
});
|
|
1041
|
+
}); });
|
|
1042
|
+
(0, bun_test_1.it)("returns 401 when refresh token is signed with wrong secret", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1043
|
+
var jwtLib, bogusToken, res;
|
|
1044
|
+
return __generator(this, function (_a) {
|
|
1045
|
+
switch (_a.label) {
|
|
1046
|
+
case 0: return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require("jsonwebtoken")); })];
|
|
1047
|
+
case 1:
|
|
1048
|
+
jwtLib = (_a.sent()).default;
|
|
1049
|
+
bogusToken = jwtLib.sign({ id: "abc" }, "different-secret");
|
|
1050
|
+
return [4 /*yield*/, agent
|
|
1051
|
+
.post("/auth/refresh_token")
|
|
1052
|
+
.send({ refreshToken: bogusToken })
|
|
1053
|
+
.expect(401)];
|
|
1054
|
+
case 2:
|
|
1055
|
+
res = _a.sent();
|
|
1056
|
+
(0, bun_test_1.expect)(res.body.message).toBeDefined();
|
|
1057
|
+
return [2 /*return*/];
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
}); });
|
|
1061
|
+
(0, bun_test_1.it)("returns 401 when refresh token has no id", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1062
|
+
var jwtLib, tokenNoId, res;
|
|
1063
|
+
return __generator(this, function (_a) {
|
|
1064
|
+
switch (_a.label) {
|
|
1065
|
+
case 0: return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require("jsonwebtoken")); })];
|
|
1066
|
+
case 1:
|
|
1067
|
+
jwtLib = (_a.sent()).default;
|
|
1068
|
+
tokenNoId = jwtLib.sign({ foo: "bar" }, process.env.REFRESH_TOKEN_SECRET);
|
|
1069
|
+
return [4 /*yield*/, agent.post("/auth/refresh_token").send({ refreshToken: tokenNoId }).expect(401)];
|
|
1070
|
+
case 2:
|
|
1071
|
+
res = _a.sent();
|
|
1072
|
+
(0, bun_test_1.expect)(res.body.message).toBe("Invalid refresh token");
|
|
1073
|
+
return [2 /*return*/];
|
|
1074
|
+
}
|
|
1075
|
+
});
|
|
1076
|
+
}); });
|
|
1077
|
+
(0, bun_test_1.it)("issues new tokens on valid refresh", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1078
|
+
var _a, adminUser, jwtLib, validToken, res;
|
|
1079
|
+
return __generator(this, function (_b) {
|
|
1080
|
+
switch (_b.label) {
|
|
1081
|
+
case 0: return [4 /*yield*/, (0, tests_1.setupDb)()];
|
|
1082
|
+
case 1:
|
|
1083
|
+
_a = __read.apply(void 0, [_b.sent(), 1]), adminUser = _a[0];
|
|
1084
|
+
return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require("jsonwebtoken")); })];
|
|
1085
|
+
case 2:
|
|
1086
|
+
jwtLib = (_b.sent()).default;
|
|
1087
|
+
validToken = jwtLib.sign({ id: adminUser._id.toString() }, process.env.REFRESH_TOKEN_SECRET);
|
|
1088
|
+
return [4 /*yield*/, agent
|
|
1089
|
+
.post("/auth/refresh_token")
|
|
1090
|
+
.send({ refreshToken: validToken })
|
|
1091
|
+
.expect(200)];
|
|
1092
|
+
case 3:
|
|
1093
|
+
res = _b.sent();
|
|
1094
|
+
(0, bun_test_1.expect)(res.body.data.token).toBeDefined();
|
|
1095
|
+
(0, bun_test_1.expect)(res.body.data.refreshToken).toBeDefined();
|
|
1096
|
+
return [2 /*return*/];
|
|
1097
|
+
}
|
|
1098
|
+
});
|
|
1099
|
+
}); });
|
|
1100
|
+
});
|
|
1101
|
+
(0, bun_test_1.describe)("addMeRoutes edge cases", function () {
|
|
1102
|
+
var app;
|
|
1103
|
+
var agent;
|
|
1104
|
+
(0, bun_test_1.beforeEach)(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1105
|
+
return __generator(this, function (_a) {
|
|
1106
|
+
switch (_a.label) {
|
|
1107
|
+
case 0:
|
|
1108
|
+
(0, bun_test_1.setSystemTime)();
|
|
1109
|
+
return [4 /*yield*/, (0, tests_1.setupDb)()];
|
|
1110
|
+
case 1:
|
|
1111
|
+
_a.sent();
|
|
1112
|
+
app = (0, expressServer_1.setupServer)({
|
|
1113
|
+
addRoutes: function () { },
|
|
1114
|
+
skipListen: true,
|
|
1115
|
+
userModel: tests_1.UserModel,
|
|
1116
|
+
});
|
|
1117
|
+
agent = supertest_1.default.agent(app);
|
|
1118
|
+
return [2 /*return*/];
|
|
1119
|
+
}
|
|
1120
|
+
});
|
|
1121
|
+
}); });
|
|
1122
|
+
(0, bun_test_1.afterEach)(function () {
|
|
1123
|
+
(0, bun_test_1.setSystemTime)();
|
|
1124
|
+
});
|
|
1125
|
+
(0, bun_test_1.it)("GET /auth/me returns 401 without auth", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1126
|
+
return __generator(this, function (_a) {
|
|
1127
|
+
switch (_a.label) {
|
|
1128
|
+
case 0: return [4 /*yield*/, agent.get("/auth/me").expect(401)];
|
|
1129
|
+
case 1:
|
|
1130
|
+
_a.sent();
|
|
1131
|
+
return [2 /*return*/];
|
|
1132
|
+
}
|
|
1133
|
+
});
|
|
1134
|
+
}); });
|
|
1135
|
+
(0, bun_test_1.it)("PATCH /auth/me returns 401 without auth", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1136
|
+
return __generator(this, function (_a) {
|
|
1137
|
+
switch (_a.label) {
|
|
1138
|
+
case 0: return [4 /*yield*/, agent.patch("/auth/me").send({ email: "x@x.com" }).expect(401)];
|
|
1139
|
+
case 1:
|
|
1140
|
+
_a.sent();
|
|
1141
|
+
return [2 /*return*/];
|
|
1142
|
+
}
|
|
1143
|
+
});
|
|
1144
|
+
}); });
|
|
1145
|
+
(0, bun_test_1.it)("GET /auth/me returns 404 when user is deleted after auth", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1146
|
+
var _a, _admin, notAdmin, jwtLib, token, res;
|
|
1147
|
+
return __generator(this, function (_b) {
|
|
1148
|
+
switch (_b.label) {
|
|
1149
|
+
case 0: return [4 /*yield*/, (0, tests_1.setupDb)()];
|
|
1150
|
+
case 1:
|
|
1151
|
+
_a = __read.apply(void 0, [_b.sent(), 2]), _admin = _a[0], notAdmin = _a[1];
|
|
1152
|
+
return [4 /*yield*/, Promise.resolve().then(function () { return __importStar(require("jsonwebtoken")); })];
|
|
1153
|
+
case 2:
|
|
1154
|
+
jwtLib = (_b.sent()).default;
|
|
1155
|
+
token = jwtLib.sign({ id: notAdmin._id.toString() }, process.env.TOKEN_SECRET, { issuer: process.env.TOKEN_ISSUER });
|
|
1156
|
+
// Delete the user so findById returns null
|
|
1157
|
+
return [4 /*yield*/, tests_1.UserModel.deleteOne({ _id: notAdmin._id })];
|
|
1158
|
+
case 3:
|
|
1159
|
+
// Delete the user so findById returns null
|
|
1160
|
+
_b.sent();
|
|
1161
|
+
return [4 /*yield*/, agent.get("/auth/me").set("authorization", "Bearer ".concat(token))];
|
|
1162
|
+
case 4:
|
|
1163
|
+
res = _b.sent();
|
|
1164
|
+
// Either 404 (user not found in /me handler) or 401 (auth middleware rejects)
|
|
1165
|
+
(0, bun_test_1.expect)([401, 404]).toContain(res.status);
|
|
1166
|
+
return [2 /*return*/];
|
|
1167
|
+
}
|
|
1168
|
+
});
|
|
1169
|
+
}); });
|
|
913
1170
|
});
|
package/dist/consentApp.test.js
CHANGED
|
@@ -1065,6 +1065,251 @@ var buildApp = function (consentAppOptions) {
|
|
|
1065
1065
|
});
|
|
1066
1066
|
}); });
|
|
1067
1067
|
});
|
|
1068
|
+
(0, bun_test_1.describe)("POST /consent-forms/generate (aiConfig)", function () {
|
|
1069
|
+
var aiConfig = {
|
|
1070
|
+
generateContent: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
1071
|
+
var type = _b.type, description = _b.description, locale = _b.locale;
|
|
1072
|
+
return __generator(this, function (_c) {
|
|
1073
|
+
return [2 /*return*/, "Generated ".concat(type, " content (").concat(locale, ") for: ").concat(description)];
|
|
1074
|
+
});
|
|
1075
|
+
}); },
|
|
1076
|
+
translateContent: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
1077
|
+
var content = _b.content, fromLocale = _b.fromLocale, toLocale = _b.toLocale;
|
|
1078
|
+
return __generator(this, function (_c) {
|
|
1079
|
+
return [2 /*return*/, "[".concat(fromLocale, "->").concat(toLocale, "] ").concat(content)];
|
|
1080
|
+
});
|
|
1081
|
+
}); },
|
|
1082
|
+
};
|
|
1083
|
+
(0, bun_test_1.it)("generates consent form content for admins", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1084
|
+
var aiApp, aiAdmin, res;
|
|
1085
|
+
return __generator(this, function (_a) {
|
|
1086
|
+
switch (_a.label) {
|
|
1087
|
+
case 0:
|
|
1088
|
+
aiApp = buildApp({ aiConfig: aiConfig });
|
|
1089
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(aiApp, "admin")];
|
|
1090
|
+
case 1:
|
|
1091
|
+
aiAdmin = _a.sent();
|
|
1092
|
+
return [4 /*yield*/, aiAdmin
|
|
1093
|
+
.post("/consent-forms/generate")
|
|
1094
|
+
.send({ description: "Privacy policy for a health app", locale: "es", type: "privacy" })
|
|
1095
|
+
.expect(200)];
|
|
1096
|
+
case 2:
|
|
1097
|
+
res = _a.sent();
|
|
1098
|
+
(0, bun_test_1.expect)(res.body.data.content).toBe("Generated privacy content (es) for: Privacy policy for a health app");
|
|
1099
|
+
return [2 /*return*/];
|
|
1100
|
+
}
|
|
1101
|
+
});
|
|
1102
|
+
}); });
|
|
1103
|
+
(0, bun_test_1.it)("defaults locale to en when not provided", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1104
|
+
var aiApp, aiAdmin, res;
|
|
1105
|
+
return __generator(this, function (_a) {
|
|
1106
|
+
switch (_a.label) {
|
|
1107
|
+
case 0:
|
|
1108
|
+
aiApp = buildApp({ aiConfig: aiConfig });
|
|
1109
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(aiApp, "admin")];
|
|
1110
|
+
case 1:
|
|
1111
|
+
aiAdmin = _a.sent();
|
|
1112
|
+
return [4 /*yield*/, aiAdmin
|
|
1113
|
+
.post("/consent-forms/generate")
|
|
1114
|
+
.send({ description: "Terms", type: "terms" })
|
|
1115
|
+
.expect(200)];
|
|
1116
|
+
case 2:
|
|
1117
|
+
res = _a.sent();
|
|
1118
|
+
(0, bun_test_1.expect)(res.body.data.content).toContain("(en)");
|
|
1119
|
+
return [2 /*return*/];
|
|
1120
|
+
}
|
|
1121
|
+
});
|
|
1122
|
+
}); });
|
|
1123
|
+
(0, bun_test_1.it)("returns 403 for non-admin users", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1124
|
+
var aiApp, aiUser;
|
|
1125
|
+
return __generator(this, function (_a) {
|
|
1126
|
+
switch (_a.label) {
|
|
1127
|
+
case 0:
|
|
1128
|
+
aiApp = buildApp({ aiConfig: aiConfig });
|
|
1129
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(aiApp, "notAdmin")];
|
|
1130
|
+
case 1:
|
|
1131
|
+
aiUser = _a.sent();
|
|
1132
|
+
return [4 /*yield*/, aiUser
|
|
1133
|
+
.post("/consent-forms/generate")
|
|
1134
|
+
.send({ description: "Privacy", type: "privacy" })
|
|
1135
|
+
.expect(403)];
|
|
1136
|
+
case 2:
|
|
1137
|
+
_a.sent();
|
|
1138
|
+
return [2 /*return*/];
|
|
1139
|
+
}
|
|
1140
|
+
});
|
|
1141
|
+
}); });
|
|
1142
|
+
(0, bun_test_1.it)("returns 400 when type is missing", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1143
|
+
var aiApp, aiAdmin;
|
|
1144
|
+
return __generator(this, function (_a) {
|
|
1145
|
+
switch (_a.label) {
|
|
1146
|
+
case 0:
|
|
1147
|
+
aiApp = buildApp({ aiConfig: aiConfig });
|
|
1148
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(aiApp, "admin")];
|
|
1149
|
+
case 1:
|
|
1150
|
+
aiAdmin = _a.sent();
|
|
1151
|
+
return [4 /*yield*/, aiAdmin.post("/consent-forms/generate").send({ description: "Privacy" }).expect(400)];
|
|
1152
|
+
case 2:
|
|
1153
|
+
_a.sent();
|
|
1154
|
+
return [2 /*return*/];
|
|
1155
|
+
}
|
|
1156
|
+
});
|
|
1157
|
+
}); });
|
|
1158
|
+
(0, bun_test_1.it)("returns 400 when description is missing", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1159
|
+
var aiApp, aiAdmin;
|
|
1160
|
+
return __generator(this, function (_a) {
|
|
1161
|
+
switch (_a.label) {
|
|
1162
|
+
case 0:
|
|
1163
|
+
aiApp = buildApp({ aiConfig: aiConfig });
|
|
1164
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(aiApp, "admin")];
|
|
1165
|
+
case 1:
|
|
1166
|
+
aiAdmin = _a.sent();
|
|
1167
|
+
return [4 /*yield*/, aiAdmin.post("/consent-forms/generate").send({ type: "privacy" }).expect(400)];
|
|
1168
|
+
case 2:
|
|
1169
|
+
_a.sent();
|
|
1170
|
+
return [2 /*return*/];
|
|
1171
|
+
}
|
|
1172
|
+
});
|
|
1173
|
+
}); });
|
|
1174
|
+
(0, bun_test_1.it)("returns 404 when aiConfig is not provided", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1175
|
+
return __generator(this, function (_a) {
|
|
1176
|
+
switch (_a.label) {
|
|
1177
|
+
case 0: return [4 /*yield*/, adminAgent
|
|
1178
|
+
.post("/consent-forms/generate")
|
|
1179
|
+
.send({ description: "Privacy", type: "privacy" })
|
|
1180
|
+
.expect(404)];
|
|
1181
|
+
case 1:
|
|
1182
|
+
_a.sent();
|
|
1183
|
+
return [2 /*return*/];
|
|
1184
|
+
}
|
|
1185
|
+
});
|
|
1186
|
+
}); });
|
|
1187
|
+
});
|
|
1188
|
+
(0, bun_test_1.describe)("POST /consent-forms/translate (aiConfig)", function () {
|
|
1189
|
+
var aiConfig = {
|
|
1190
|
+
generateContent: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
1191
|
+
var type = _b.type, description = _b.description, locale = _b.locale;
|
|
1192
|
+
return __generator(this, function (_c) {
|
|
1193
|
+
return [2 /*return*/, "Generated ".concat(type, " content (").concat(locale, ") for: ").concat(description)];
|
|
1194
|
+
});
|
|
1195
|
+
}); },
|
|
1196
|
+
translateContent: function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
1197
|
+
var content = _b.content, fromLocale = _b.fromLocale, toLocale = _b.toLocale;
|
|
1198
|
+
return __generator(this, function (_c) {
|
|
1199
|
+
return [2 /*return*/, "[".concat(fromLocale, "->").concat(toLocale, "] ").concat(content)];
|
|
1200
|
+
});
|
|
1201
|
+
}); },
|
|
1202
|
+
};
|
|
1203
|
+
(0, bun_test_1.it)("translates consent form content for admins", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1204
|
+
var aiApp, aiAdmin, res;
|
|
1205
|
+
return __generator(this, function (_a) {
|
|
1206
|
+
switch (_a.label) {
|
|
1207
|
+
case 0:
|
|
1208
|
+
aiApp = buildApp({ aiConfig: aiConfig });
|
|
1209
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(aiApp, "admin")];
|
|
1210
|
+
case 1:
|
|
1211
|
+
aiAdmin = _a.sent();
|
|
1212
|
+
return [4 /*yield*/, aiAdmin
|
|
1213
|
+
.post("/consent-forms/translate")
|
|
1214
|
+
.send({ content: "Hello world", fromLocale: "en", toLocale: "es" })
|
|
1215
|
+
.expect(200)];
|
|
1216
|
+
case 2:
|
|
1217
|
+
res = _a.sent();
|
|
1218
|
+
(0, bun_test_1.expect)(res.body.data.content).toBe("[en->es] Hello world");
|
|
1219
|
+
return [2 /*return*/];
|
|
1220
|
+
}
|
|
1221
|
+
});
|
|
1222
|
+
}); });
|
|
1223
|
+
(0, bun_test_1.it)("returns 403 for non-admin users", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1224
|
+
var aiApp, aiUser;
|
|
1225
|
+
return __generator(this, function (_a) {
|
|
1226
|
+
switch (_a.label) {
|
|
1227
|
+
case 0:
|
|
1228
|
+
aiApp = buildApp({ aiConfig: aiConfig });
|
|
1229
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(aiApp, "notAdmin")];
|
|
1230
|
+
case 1:
|
|
1231
|
+
aiUser = _a.sent();
|
|
1232
|
+
return [4 /*yield*/, aiUser
|
|
1233
|
+
.post("/consent-forms/translate")
|
|
1234
|
+
.send({ content: "Hello", fromLocale: "en", toLocale: "es" })
|
|
1235
|
+
.expect(403)];
|
|
1236
|
+
case 2:
|
|
1237
|
+
_a.sent();
|
|
1238
|
+
return [2 /*return*/];
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
1241
|
+
}); });
|
|
1242
|
+
(0, bun_test_1.it)("returns 400 when content is missing", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1243
|
+
var aiApp, aiAdmin;
|
|
1244
|
+
return __generator(this, function (_a) {
|
|
1245
|
+
switch (_a.label) {
|
|
1246
|
+
case 0:
|
|
1247
|
+
aiApp = buildApp({ aiConfig: aiConfig });
|
|
1248
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(aiApp, "admin")];
|
|
1249
|
+
case 1:
|
|
1250
|
+
aiAdmin = _a.sent();
|
|
1251
|
+
return [4 /*yield*/, aiAdmin
|
|
1252
|
+
.post("/consent-forms/translate")
|
|
1253
|
+
.send({ fromLocale: "en", toLocale: "es" })
|
|
1254
|
+
.expect(400)];
|
|
1255
|
+
case 2:
|
|
1256
|
+
_a.sent();
|
|
1257
|
+
return [2 /*return*/];
|
|
1258
|
+
}
|
|
1259
|
+
});
|
|
1260
|
+
}); });
|
|
1261
|
+
(0, bun_test_1.it)("returns 400 when fromLocale is missing", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1262
|
+
var aiApp, aiAdmin;
|
|
1263
|
+
return __generator(this, function (_a) {
|
|
1264
|
+
switch (_a.label) {
|
|
1265
|
+
case 0:
|
|
1266
|
+
aiApp = buildApp({ aiConfig: aiConfig });
|
|
1267
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(aiApp, "admin")];
|
|
1268
|
+
case 1:
|
|
1269
|
+
aiAdmin = _a.sent();
|
|
1270
|
+
return [4 /*yield*/, aiAdmin
|
|
1271
|
+
.post("/consent-forms/translate")
|
|
1272
|
+
.send({ content: "Hello", toLocale: "es" })
|
|
1273
|
+
.expect(400)];
|
|
1274
|
+
case 2:
|
|
1275
|
+
_a.sent();
|
|
1276
|
+
return [2 /*return*/];
|
|
1277
|
+
}
|
|
1278
|
+
});
|
|
1279
|
+
}); });
|
|
1280
|
+
(0, bun_test_1.it)("returns 400 when toLocale is missing", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1281
|
+
var aiApp, aiAdmin;
|
|
1282
|
+
return __generator(this, function (_a) {
|
|
1283
|
+
switch (_a.label) {
|
|
1284
|
+
case 0:
|
|
1285
|
+
aiApp = buildApp({ aiConfig: aiConfig });
|
|
1286
|
+
return [4 /*yield*/, (0, tests_1.authAsUser)(aiApp, "admin")];
|
|
1287
|
+
case 1:
|
|
1288
|
+
aiAdmin = _a.sent();
|
|
1289
|
+
return [4 /*yield*/, aiAdmin
|
|
1290
|
+
.post("/consent-forms/translate")
|
|
1291
|
+
.send({ content: "Hello", fromLocale: "en" })
|
|
1292
|
+
.expect(400)];
|
|
1293
|
+
case 2:
|
|
1294
|
+
_a.sent();
|
|
1295
|
+
return [2 /*return*/];
|
|
1296
|
+
}
|
|
1297
|
+
});
|
|
1298
|
+
}); });
|
|
1299
|
+
(0, bun_test_1.it)("returns 404 when aiConfig is not provided", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1300
|
+
return __generator(this, function (_a) {
|
|
1301
|
+
switch (_a.label) {
|
|
1302
|
+
case 0: return [4 /*yield*/, adminAgent
|
|
1303
|
+
.post("/consent-forms/translate")
|
|
1304
|
+
.send({ content: "Hello", fromLocale: "en", toLocale: "es" })
|
|
1305
|
+
.expect(404)];
|
|
1306
|
+
case 1:
|
|
1307
|
+
_a.sent();
|
|
1308
|
+
return [2 /*return*/];
|
|
1309
|
+
}
|
|
1310
|
+
});
|
|
1311
|
+
}); });
|
|
1312
|
+
});
|
|
1068
1313
|
(0, bun_test_1.describe)("GET /consents/audit/:userId", function () {
|
|
1069
1314
|
(0, bun_test_1.it)("returns audit history for a user when auditTrail is enabled", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
1070
1315
|
var form, res;
|
package/dist/expressServer.js
CHANGED
|
@@ -341,16 +341,10 @@ function setupServer(options) {
|
|
|
341
341
|
}
|
|
342
342
|
// Convenience method to execute cronjobs with an always-running server.
|
|
343
343
|
function cronjob(name, schedule, callback) {
|
|
344
|
-
var
|
|
345
|
-
|
|
346
|
-
_cronSchedule = "0 * * * *";
|
|
347
|
-
}
|
|
348
|
-
else if (schedule === "minutely") {
|
|
349
|
-
_cronSchedule = "* * * * *";
|
|
350
|
-
}
|
|
351
|
-
logger_1.logger.info("Adding cronjob ".concat(name, ", running at: ").concat(schedule));
|
|
344
|
+
var cronSchedule = schedule === "hourly" ? "0 * * * *" : schedule === "minutely" ? "* * * * *" : schedule;
|
|
345
|
+
logger_1.logger.info("Adding cronjob ".concat(name, ", running at: ").concat(cronSchedule));
|
|
352
346
|
try {
|
|
353
|
-
new cron_1.default.CronJob(
|
|
347
|
+
new cron_1.default.CronJob(cronSchedule, callback, null, true, "America/Chicago");
|
|
354
348
|
}
|
|
355
349
|
catch (error) {
|
|
356
350
|
throw new Error("Failed to create cronjob: ".concat(error));
|
|
@@ -383,16 +383,13 @@ var tests_1 = require("./tests");
|
|
|
383
383
|
var callback = function () { };
|
|
384
384
|
(0, bun_test_1.expect)(function () { return (0, expressServer_1.cronjob)("test-invalid", "invalid-cron", callback); }).toThrow("Failed to create cronjob");
|
|
385
385
|
});
|
|
386
|
-
|
|
387
|
-
// schedule to a cron expression but then use the original schedule string.
|
|
388
|
-
// This test documents that current (buggy) behavior.
|
|
389
|
-
(0, bun_test_1.it)("hourly alias fails due to bug in implementation", function () {
|
|
386
|
+
(0, bun_test_1.it)("accepts hourly alias", function () {
|
|
390
387
|
var callback = function () { };
|
|
391
|
-
(0, bun_test_1.expect)(function () { return (0, expressServer_1.cronjob)("test-hourly-alias", "hourly", callback); }).toThrow(
|
|
388
|
+
(0, bun_test_1.expect)(function () { return (0, expressServer_1.cronjob)("test-hourly-alias", "hourly", callback); }).not.toThrow();
|
|
392
389
|
});
|
|
393
|
-
(0, bun_test_1.it)("minutely alias
|
|
390
|
+
(0, bun_test_1.it)("accepts minutely alias", function () {
|
|
394
391
|
var callback = function () { };
|
|
395
|
-
(0, bun_test_1.expect)(function () { return (0, expressServer_1.cronjob)("test-minutely-alias", "minutely", callback); }).toThrow(
|
|
392
|
+
(0, bun_test_1.expect)(function () { return (0, expressServer_1.cronjob)("test-minutely-alias", "minutely", callback); }).not.toThrow();
|
|
396
393
|
});
|
|
397
394
|
});
|
|
398
395
|
(0, bun_test_1.describe)("createRouter routePathMiddleware", function () {
|