@terreno/api 0.10.0 → 0.11.1
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/dist/auth.test.js +257 -0
- package/dist/consentApp.test.js +245 -0
- 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 +122 -0
- package/dist/openApiBuilder.d.ts +1 -0
- package/dist/openApiBuilder.js +13 -2
- package/dist/openApiBuilder.test.js +66 -0
- package/dist/openApiValidator.test.js +309 -0
- package/dist/plugins.d.ts +8 -8
- package/dist/plugins.js +38 -32
- package/dist/populate.test.js +99 -0
- package/dist/syncConsents.test.js +273 -0
- 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/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 +152 -0
- package/src/openApi.ts +6 -2
- package/src/openApiBuilder.test.ts +81 -0
- package/src/openApiBuilder.ts +17 -2
- package/src/openApiValidator.test.ts +410 -0
- package/src/plugins.ts +32 -23
- package/src/populate.test.ts +78 -2
- package/src/syncConsents.test.ts +145 -0
- 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/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;
|