@proteinjs/user-server 1.5.4 → 1.6.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/CHANGELOG.md +17 -0
- package/dist/generated/index.d.ts +1 -4
- package/dist/generated/index.d.ts.map +1 -1
- package/dist/generated/index.js +4 -5
- package/dist/generated/index.js.map +1 -1
- package/dist/src/routes/avatar.d.ts +19 -0
- package/dist/src/routes/avatar.d.ts.map +1 -0
- package/dist/src/routes/avatar.js +108 -0
- package/dist/src/routes/avatar.js.map +1 -0
- package/dist/src/routes/devLogin.d.ts.map +1 -1
- package/dist/src/routes/devLogin.js +11 -0
- package/dist/src/routes/devLogin.js.map +1 -1
- package/dist/src/services/UpdateUserInfo.d.ts +40 -2
- package/dist/src/services/UpdateUserInfo.d.ts.map +1 -1
- package/dist/src/services/UpdateUserInfo.js +183 -12
- package/dist/src/services/UpdateUserInfo.js.map +1 -1
- package/dist/test/UpdateUserInfoAvatar.test.d.ts +2 -0
- package/dist/test/UpdateUserInfoAvatar.test.d.ts.map +1 -0
- package/dist/test/UpdateUserInfoAvatar.test.js +337 -0
- package/dist/test/UpdateUserInfoAvatar.test.js.map +1 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.d.ts +2 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.d.ts.map +1 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.js +94 -0
- package/dist/test/UpdateUserInfoSessionRefresh.test.js.map +1 -0
- package/dist/test/UserServerTestEnvironment.d.ts +26 -0
- package/dist/test/UserServerTestEnvironment.d.ts.map +1 -0
- package/dist/test/UserServerTestEnvironment.js +202 -0
- package/dist/test/UserServerTestEnvironment.js.map +1 -0
- package/dist/test/avatarRoute.test.d.ts +2 -0
- package/dist/test/avatarRoute.test.d.ts.map +1 -0
- package/dist/test/avatarRoute.test.js +222 -0
- package/dist/test/avatarRoute.test.js.map +1 -0
- package/generated/index.ts +4 -5
- package/jest.config.js +4 -1
- package/package.json +8 -5
- package/src/heic-decode.d.ts +13 -0
- package/src/routes/avatar.ts +57 -0
- package/src/routes/devLogin.ts +5 -0
- package/src/services/UpdateUserInfo.ts +124 -13
- package/test/UpdateUserInfoAvatar.test.ts +174 -0
- package/test/UpdateUserInfoSessionRefresh.test.ts +37 -0
- package/test/UserServerTestEnvironment.ts +97 -0
- package/test/avatarRoute.test.ts +111 -0
- package/test/emulatorLock.globalSetup.js +11 -0
- package/test/emulatorLock.globalTeardown.js +8 -0
- package/test/emulatorLock.js +124 -0
- package/test/fixtures/fixture.heic +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
var db_1 = require("@proteinjs/db");
|
|
40
|
+
var user_1 = require("@proteinjs/user");
|
|
41
|
+
var UserServerTestEnvironment_1 = require("./UserServerTestEnvironment");
|
|
42
|
+
var UpdateUserInfo_1 = require("../src/services/UpdateUserInfo");
|
|
43
|
+
var testEnv = new UserServerTestEnvironment_1.UserServerTestEnvironment();
|
|
44
|
+
/**
|
|
45
|
+
* The rename-staleness wart, red-before-green: UpdateUserInfo.updateName wrote the DB but never
|
|
46
|
+
* refreshed the server session cache (userCache serializes the user into session data), so every
|
|
47
|
+
* read through UserRepo in the same request context — and any long-lived context that keeps its
|
|
48
|
+
* session data, e.g. socket sessions — kept serving the OLD name until re-login. The fix routes
|
|
49
|
+
* every user-info mutation through one helper that persists AND refreshes the session cache.
|
|
50
|
+
*/
|
|
51
|
+
describe('UpdateUserInfo.updateName — persists AND refreshes the server session cache', function () {
|
|
52
|
+
beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
53
|
+
return __generator(this, function (_a) {
|
|
54
|
+
switch (_a.label) {
|
|
55
|
+
case 0: return [4 /*yield*/, testEnv.beforeAll()];
|
|
56
|
+
case 1:
|
|
57
|
+
_a.sent();
|
|
58
|
+
return [2 /*return*/];
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}); });
|
|
62
|
+
afterAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
63
|
+
return __generator(this, function (_a) {
|
|
64
|
+
switch (_a.label) {
|
|
65
|
+
case 0: return [4 /*yield*/, testEnv.afterAll()];
|
|
66
|
+
case 1:
|
|
67
|
+
_a.sent();
|
|
68
|
+
return [2 /*return*/];
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
}); });
|
|
72
|
+
it('updates the user row and the session-cached user in the same stroke', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
73
|
+
var user, row;
|
|
74
|
+
return __generator(this, function (_a) {
|
|
75
|
+
switch (_a.label) {
|
|
76
|
+
case 0: return [4 /*yield*/, testEnv.createUser({ name: 'Old Name', email: 'rename@test.local' })];
|
|
77
|
+
case 1:
|
|
78
|
+
user = _a.sent();
|
|
79
|
+
testEnv.actAs(user);
|
|
80
|
+
return [4 /*yield*/, new UpdateUserInfo_1.UpdateUserInfo().updateName('New Name')];
|
|
81
|
+
case 2:
|
|
82
|
+
_a.sent();
|
|
83
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(user_1.tables.User, { id: user.id })];
|
|
84
|
+
case 3:
|
|
85
|
+
row = _a.sent();
|
|
86
|
+
expect(row.name).toBe('New Name');
|
|
87
|
+
// Outcome 2 (the wart): the session cache must serve the new name too. RED pre-fix.
|
|
88
|
+
expect(new user_1.UserRepo().getUser().name).toBe('New Name');
|
|
89
|
+
return [2 /*return*/];
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}); });
|
|
93
|
+
});
|
|
94
|
+
//# sourceMappingURL=UpdateUserInfoSessionRefresh.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UpdateUserInfoSessionRefresh.test.js","sourceRoot":"","sources":["../../test/UpdateUserInfoSessionRefresh.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAA8C;AAC9C,wCAAmD;AACnD,yEAAwE;AACxE,iEAAgE;AAEhE,IAAM,OAAO,GAAG,IAAI,qDAAyB,EAAE,CAAC;AAEhD;;;;;;GAMG;AACH,QAAQ,CAAC,6EAA6E,EAAE;IACtF,SAAS,CAAC;;;wBACR,qBAAM,OAAO,CAAC,SAAS,EAAE,EAAA;;oBAAzB,SAAyB,CAAC;;;;SAC3B,CAAC,CAAC;IAEH,QAAQ,CAAC;;;wBACP,qBAAM,OAAO,CAAC,QAAQ,EAAE,EAAA;;oBAAxB,SAAwB,CAAC;;;;SAC1B,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE;;;;wBAC3D,qBAAM,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,EAAA;;oBAAjF,IAAI,GAAG,SAA0E;oBACvF,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAEpB,qBAAM,IAAI,+BAAc,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAA;;oBAAjD,SAAiD,CAAC;oBAGtC,qBAAM,IAAA,kBAAa,GAAE,CAAC,GAAG,CAAC,aAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAAA;;oBAA7D,GAAG,GAAG,SAAuD;oBACnE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAElC,oFAAoF;oBACpF,MAAM,CAAC,IAAI,eAAQ,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;;;;SACxD,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { SpannerDriver } from '@proteinjs/db-driver-spanner';
|
|
2
|
+
import { User } from '@proteinjs/user';
|
|
3
|
+
/**
|
|
4
|
+
* Emulator-backed test environment for user-server integration tests (Spanner emulator on
|
|
5
|
+
* SPANNER_EMULATOR_HOST, provisioned on demand). Same shape as chat-server's ChatTestEnvironment:
|
|
6
|
+
* seed deterministic session storage + db driver into the SourceRepository cache, load the tables
|
|
7
|
+
* the suites touch, drop them on the way out.
|
|
8
|
+
*/
|
|
9
|
+
export declare class UserServerTestEnvironment {
|
|
10
|
+
readonly spannerDriver: SpannerDriver;
|
|
11
|
+
private dropTestTable;
|
|
12
|
+
private userRepo;
|
|
13
|
+
beforeAll(): Promise<void>;
|
|
14
|
+
afterAll(): Promise<void>;
|
|
15
|
+
/** Insert a user row (as system) and return it. */
|
|
16
|
+
createUser(args: {
|
|
17
|
+
name: string;
|
|
18
|
+
email: string;
|
|
19
|
+
roles?: string[];
|
|
20
|
+
}): Promise<User>;
|
|
21
|
+
/** Seed the session cache with `user` — the identity service calls and scoped db ops run under. */
|
|
22
|
+
actAs(user: User): void;
|
|
23
|
+
private loadTables;
|
|
24
|
+
private dropTables;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=UserServerTestEnvironment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserServerTestEnvironment.d.ts","sourceRoot":"","sources":["../../test/UserServerTestEnvironment.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAK7D,OAAO,EAAwB,IAAI,EAAY,MAAM,iBAAiB,CAAC;AAmBvE;;;;;GAKG;AACH,qBAAa,yBAAyB;IACpC,QAAQ,CAAC,aAAa,gBAInB;IACH,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,QAAQ,CAAkB;IAE5B,SAAS;IAqBT,QAAQ;IAMd,mDAAmD;IAC7C,UAAU,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAUxF,mGAAmG;IACnG,KAAK,CAAC,IAAI,EAAE,IAAI;YAIF,UAAU;YAOV,UAAU;CAKzB"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.UserServerTestEnvironment = void 0;
|
|
40
|
+
var db_1 = require("@proteinjs/db");
|
|
41
|
+
var db_driver_spanner_1 = require("@proteinjs/db-driver-spanner");
|
|
42
|
+
var test_1 = require("@proteinjs/db-driver-spanner/test");
|
|
43
|
+
var db_file_1 = require("@proteinjs/db-file");
|
|
44
|
+
var server_api_1 = require("@proteinjs/server-api");
|
|
45
|
+
var reflection_1 = require("@proteinjs/reflection");
|
|
46
|
+
var user_1 = require("@proteinjs/user");
|
|
47
|
+
/** In-memory SessionDataStorage seeded into the SourceRepository cache (tests don't load the
|
|
48
|
+
* generated source graph, so `Session` would otherwise find no implementation). */
|
|
49
|
+
var TestSessionDataStorage = /** @class */ (function () {
|
|
50
|
+
function TestSessionDataStorage() {
|
|
51
|
+
this.environment = 'node';
|
|
52
|
+
}
|
|
53
|
+
TestSessionDataStorage.prototype.setData = function (data) {
|
|
54
|
+
TestSessionDataStorage.data = data;
|
|
55
|
+
};
|
|
56
|
+
TestSessionDataStorage.prototype.getData = function () {
|
|
57
|
+
return TestSessionDataStorage.data;
|
|
58
|
+
};
|
|
59
|
+
return TestSessionDataStorage;
|
|
60
|
+
}());
|
|
61
|
+
/**
|
|
62
|
+
* Emulator-backed test environment for user-server integration tests (Spanner emulator on
|
|
63
|
+
* SPANNER_EMULATOR_HOST, provisioned on demand). Same shape as chat-server's ChatTestEnvironment:
|
|
64
|
+
* seed deterministic session storage + db driver into the SourceRepository cache, load the tables
|
|
65
|
+
* the suites touch, drop them on the way out.
|
|
66
|
+
*/
|
|
67
|
+
var UserServerTestEnvironment = /** @class */ (function () {
|
|
68
|
+
function UserServerTestEnvironment() {
|
|
69
|
+
this.spannerDriver = new db_driver_spanner_1.SpannerDriver({
|
|
70
|
+
projectId: 'proteinjs-test',
|
|
71
|
+
instanceName: 'proteinjs-test',
|
|
72
|
+
databaseName: 'test',
|
|
73
|
+
});
|
|
74
|
+
this.dropTestTable = (0, test_1.getDropTestTable)(this.spannerDriver);
|
|
75
|
+
this.userRepo = new user_1.UserRepo();
|
|
76
|
+
}
|
|
77
|
+
UserServerTestEnvironment.prototype.beforeAll = function () {
|
|
78
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
79
|
+
var objectCache;
|
|
80
|
+
var _this = this;
|
|
81
|
+
return __generator(this, function (_a) {
|
|
82
|
+
switch (_a.label) {
|
|
83
|
+
case 0:
|
|
84
|
+
// The emulator wipes its in-memory instances on any container restart (and CI service
|
|
85
|
+
// containers start empty) — self-provision so suites never depend on out-of-band setup.
|
|
86
|
+
return [4 /*yield*/, test_1.SpannerEmulatorProvisioner.ensureProvisioned({
|
|
87
|
+
projectId: 'proteinjs-test',
|
|
88
|
+
instanceName: 'proteinjs-test',
|
|
89
|
+
databaseName: 'test',
|
|
90
|
+
})];
|
|
91
|
+
case 1:
|
|
92
|
+
// The emulator wipes its in-memory instances on any container restart (and CI service
|
|
93
|
+
// containers start empty) — self-provision so suites never depend on out-of-band setup.
|
|
94
|
+
_a.sent();
|
|
95
|
+
objectCache = reflection_1.SourceRepository.get().objectCache;
|
|
96
|
+
objectCache['@proteinjs/server-api/SessionDataStorage'] = [new TestSessionDataStorage()];
|
|
97
|
+
objectCache['@proteinjs/db/DefaultDbDriverFactory'] = [{ getDbDriver: function () { return _this.spannerDriver; } }];
|
|
98
|
+
server_api_1.Session.setData({
|
|
99
|
+
sessionId: 'test-session',
|
|
100
|
+
user: 'guest',
|
|
101
|
+
data: {},
|
|
102
|
+
});
|
|
103
|
+
return [4 /*yield*/, this.loadTables(user_1.tables)];
|
|
104
|
+
case 2:
|
|
105
|
+
_a.sent();
|
|
106
|
+
return [4 /*yield*/, this.loadTables(db_file_1.tables)];
|
|
107
|
+
case 3:
|
|
108
|
+
_a.sent();
|
|
109
|
+
return [2 /*return*/];
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
UserServerTestEnvironment.prototype.afterAll = function () {
|
|
115
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
116
|
+
return __generator(this, function (_a) {
|
|
117
|
+
switch (_a.label) {
|
|
118
|
+
case 0: return [4 /*yield*/, this.dropTables(db_file_1.tables)];
|
|
119
|
+
case 1:
|
|
120
|
+
_a.sent();
|
|
121
|
+
return [4 /*yield*/, this.dropTables(user_1.tables)];
|
|
122
|
+
case 2:
|
|
123
|
+
_a.sent();
|
|
124
|
+
test_1.SpannerEmulatorProvisioner.release();
|
|
125
|
+
return [2 /*return*/];
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
};
|
|
130
|
+
/** Insert a user row (as system) and return it. */
|
|
131
|
+
UserServerTestEnvironment.prototype.createUser = function (args) {
|
|
132
|
+
var _a;
|
|
133
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
134
|
+
return __generator(this, function (_b) {
|
|
135
|
+
switch (_b.label) {
|
|
136
|
+
case 0: return [4 /*yield*/, (0, db_1.getDbAsSystem)().insert(user_1.tables.User, {
|
|
137
|
+
name: args.name,
|
|
138
|
+
email: args.email,
|
|
139
|
+
password: 'test',
|
|
140
|
+
emailVerified: true,
|
|
141
|
+
roles: (_a = args.roles) !== null && _a !== void 0 ? _a : [],
|
|
142
|
+
})];
|
|
143
|
+
case 1: return [2 /*return*/, _b.sent()];
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
};
|
|
148
|
+
/** Seed the session cache with `user` — the identity service calls and scoped db ops run under. */
|
|
149
|
+
UserServerTestEnvironment.prototype.actAs = function (user) {
|
|
150
|
+
this.userRepo.setUser(user);
|
|
151
|
+
};
|
|
152
|
+
UserServerTestEnvironment.prototype.loadTables = function (tables) {
|
|
153
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
154
|
+
var dbDriver, _i, _a, table;
|
|
155
|
+
return __generator(this, function (_b) {
|
|
156
|
+
switch (_b.label) {
|
|
157
|
+
case 0:
|
|
158
|
+
dbDriver = db_1.Db.getDefaultDbDriver();
|
|
159
|
+
_i = 0, _a = Object.values(tables);
|
|
160
|
+
_b.label = 1;
|
|
161
|
+
case 1:
|
|
162
|
+
if (!(_i < _a.length)) return [3 /*break*/, 4];
|
|
163
|
+
table = _a[_i];
|
|
164
|
+
return [4 /*yield*/, dbDriver.getTableManager().loadTable(table)];
|
|
165
|
+
case 2:
|
|
166
|
+
_b.sent();
|
|
167
|
+
_b.label = 3;
|
|
168
|
+
case 3:
|
|
169
|
+
_i++;
|
|
170
|
+
return [3 /*break*/, 1];
|
|
171
|
+
case 4: return [2 /*return*/];
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
UserServerTestEnvironment.prototype.dropTables = function (tables) {
|
|
177
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
178
|
+
var _i, _a, table;
|
|
179
|
+
return __generator(this, function (_b) {
|
|
180
|
+
switch (_b.label) {
|
|
181
|
+
case 0:
|
|
182
|
+
_i = 0, _a = Object.values(tables);
|
|
183
|
+
_b.label = 1;
|
|
184
|
+
case 1:
|
|
185
|
+
if (!(_i < _a.length)) return [3 /*break*/, 4];
|
|
186
|
+
table = _a[_i];
|
|
187
|
+
return [4 /*yield*/, this.dropTestTable(table)];
|
|
188
|
+
case 2:
|
|
189
|
+
_b.sent();
|
|
190
|
+
_b.label = 3;
|
|
191
|
+
case 3:
|
|
192
|
+
_i++;
|
|
193
|
+
return [3 /*break*/, 1];
|
|
194
|
+
case 4: return [2 /*return*/];
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
};
|
|
199
|
+
return UserServerTestEnvironment;
|
|
200
|
+
}());
|
|
201
|
+
exports.UserServerTestEnvironment = UserServerTestEnvironment;
|
|
202
|
+
//# sourceMappingURL=UserServerTestEnvironment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserServerTestEnvironment.js","sourceRoot":"","sources":["../../test/UserServerTestEnvironment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatarRoute.test.d.ts","sourceRoot":"","sources":["../../test/avatarRoute.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
+
};
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
var sharp_1 = __importDefault(require("sharp"));
|
|
43
|
+
var user_1 = require("@proteinjs/user");
|
|
44
|
+
var UserServerTestEnvironment_1 = require("./UserServerTestEnvironment");
|
|
45
|
+
var UpdateUserInfo_1 = require("../src/services/UpdateUserInfo");
|
|
46
|
+
var avatar_1 = require("../src/routes/avatar");
|
|
47
|
+
var testEnv = new UserServerTestEnvironment_1.UserServerTestEnvironment();
|
|
48
|
+
/** Captures exactly what the route writes — status, headers, body. */
|
|
49
|
+
var MockResponse = /** @class */ (function () {
|
|
50
|
+
function MockResponse() {
|
|
51
|
+
this.statusCode = 200;
|
|
52
|
+
this.headers = {};
|
|
53
|
+
}
|
|
54
|
+
MockResponse.prototype.status = function (code) {
|
|
55
|
+
this.statusCode = code;
|
|
56
|
+
return this;
|
|
57
|
+
};
|
|
58
|
+
MockResponse.prototype.setHeader = function (name, value) {
|
|
59
|
+
this.headers[name.toLowerCase()] = value;
|
|
60
|
+
};
|
|
61
|
+
MockResponse.prototype.send = function (body) {
|
|
62
|
+
this.body = body;
|
|
63
|
+
return this;
|
|
64
|
+
};
|
|
65
|
+
return MockResponse;
|
|
66
|
+
}());
|
|
67
|
+
var requestAvatar = function (userId) { return __awaiter(void 0, void 0, void 0, function () {
|
|
68
|
+
var response;
|
|
69
|
+
return __generator(this, function (_a) {
|
|
70
|
+
switch (_a.label) {
|
|
71
|
+
case 0:
|
|
72
|
+
response = new MockResponse();
|
|
73
|
+
return [4 /*yield*/, avatar_1.avatar.onRequest({ params: { userId: userId } }, response)];
|
|
74
|
+
case 1:
|
|
75
|
+
_a.sent();
|
|
76
|
+
return [2 /*return*/, response];
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
}); };
|
|
80
|
+
/**
|
|
81
|
+
* The shared-visibility door for avatar photos: logged-in users can render ANY user's avatar
|
|
82
|
+
* (File rows are ScopedRecords, so /file/:id can't serve them cross-user); logged-out requests
|
|
83
|
+
* get 401; emoji/no-avatar users get 404 (clients render emoji/initials from the user record).
|
|
84
|
+
* Only the file id stored on the user row is ever served.
|
|
85
|
+
*/
|
|
86
|
+
describe('GET /avatar/:userId', function () {
|
|
87
|
+
beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
88
|
+
return __generator(this, function (_a) {
|
|
89
|
+
switch (_a.label) {
|
|
90
|
+
case 0: return [4 /*yield*/, testEnv.beforeAll()];
|
|
91
|
+
case 1:
|
|
92
|
+
_a.sent();
|
|
93
|
+
return [2 /*return*/];
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}); });
|
|
97
|
+
afterAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
98
|
+
return __generator(this, function (_a) {
|
|
99
|
+
switch (_a.label) {
|
|
100
|
+
case 0: return [4 /*yield*/, testEnv.afterAll()];
|
|
101
|
+
case 1:
|
|
102
|
+
_a.sent();
|
|
103
|
+
return [2 /*return*/];
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}); });
|
|
107
|
+
it("serves another user's avatar photo to any logged-in (non-admin) user, cacheable by fileId", function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
108
|
+
var owner, png, updated, viewer, response, bytes, metadata;
|
|
109
|
+
return __generator(this, function (_a) {
|
|
110
|
+
switch (_a.label) {
|
|
111
|
+
case 0: return [4 /*yield*/, testEnv.createUser({ name: 'Owner', email: 'owner@test.local' })];
|
|
112
|
+
case 1:
|
|
113
|
+
owner = _a.sent();
|
|
114
|
+
testEnv.actAs(owner);
|
|
115
|
+
return [4 /*yield*/, (0, sharp_1.default)({ create: { width: 100, height: 100, channels: 3, background: { r: 5, g: 150, b: 90 } } })
|
|
116
|
+
.png()
|
|
117
|
+
.toBuffer()];
|
|
118
|
+
case 2:
|
|
119
|
+
png = _a.sent();
|
|
120
|
+
return [4 /*yield*/, new UpdateUserInfo_1.UpdateUserInfo().updateAvatarPhoto(png.toString('base64'), 'image/png')];
|
|
121
|
+
case 3:
|
|
122
|
+
updated = _a.sent();
|
|
123
|
+
return [4 /*yield*/, testEnv.createUser({ name: 'Viewer', email: 'viewer@test.local', roles: [] })];
|
|
124
|
+
case 4:
|
|
125
|
+
viewer = _a.sent();
|
|
126
|
+
testEnv.actAs(viewer);
|
|
127
|
+
return [4 /*yield*/, requestAvatar(owner.id)];
|
|
128
|
+
case 5:
|
|
129
|
+
response = _a.sent();
|
|
130
|
+
expect(response.statusCode).toBe(200);
|
|
131
|
+
expect(response.headers['content-type']).toBe('image/jpeg');
|
|
132
|
+
expect(response.headers['cache-control']).toBe('public, max-age=86400, immutable');
|
|
133
|
+
bytes = response.body;
|
|
134
|
+
expect(Buffer.isBuffer(bytes)).toBe(true);
|
|
135
|
+
expect(bytes[0]).toBe(0xff); // JPEG SOI
|
|
136
|
+
expect(bytes[1]).toBe(0xd8);
|
|
137
|
+
return [4 /*yield*/, (0, sharp_1.default)(bytes).metadata()];
|
|
138
|
+
case 6:
|
|
139
|
+
metadata = _a.sent();
|
|
140
|
+
expect(metadata.width).toBe(512);
|
|
141
|
+
expect(metadata.height).toBe(512);
|
|
142
|
+
// The client-side URL contract carries the cache-buster.
|
|
143
|
+
expect(user_1.avatarRoute.path(owner.id, updated.avatarFileId)).toBe("/avatar/".concat(owner.id, "?v=").concat(updated.avatarFileId));
|
|
144
|
+
return [2 /*return*/];
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
}); });
|
|
148
|
+
it('404s for an emoji-avatar user and a no-avatar user (photos only)', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
149
|
+
var emojiUser, bareUser, _a, _b;
|
|
150
|
+
return __generator(this, function (_c) {
|
|
151
|
+
switch (_c.label) {
|
|
152
|
+
case 0: return [4 /*yield*/, testEnv.createUser({ name: 'Emoji', email: 'emoji-route@test.local' })];
|
|
153
|
+
case 1:
|
|
154
|
+
emojiUser = _c.sent();
|
|
155
|
+
testEnv.actAs(emojiUser);
|
|
156
|
+
return [4 /*yield*/, new UpdateUserInfo_1.UpdateUserInfo().updateAvatarEmoji('🦀')];
|
|
157
|
+
case 2:
|
|
158
|
+
_c.sent();
|
|
159
|
+
return [4 /*yield*/, testEnv.createUser({ name: 'Bare', email: 'bare-route@test.local' })];
|
|
160
|
+
case 3:
|
|
161
|
+
bareUser = _c.sent();
|
|
162
|
+
testEnv.actAs(bareUser);
|
|
163
|
+
_a = expect;
|
|
164
|
+
return [4 /*yield*/, requestAvatar(emojiUser.id)];
|
|
165
|
+
case 4:
|
|
166
|
+
_a.apply(void 0, [(_c.sent()).statusCode]).toBe(404);
|
|
167
|
+
_b = expect;
|
|
168
|
+
return [4 /*yield*/, requestAvatar(bareUser.id)];
|
|
169
|
+
case 5:
|
|
170
|
+
_b.apply(void 0, [(_c.sent()).statusCode]).toBe(404);
|
|
171
|
+
return [2 /*return*/];
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
}); });
|
|
175
|
+
it('404s for unknown ids — :userId is a keyed lookup, never a path', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
176
|
+
var viewer, _a, _b;
|
|
177
|
+
return __generator(this, function (_c) {
|
|
178
|
+
switch (_c.label) {
|
|
179
|
+
case 0: return [4 /*yield*/, testEnv.createUser({ name: 'Curious', email: 'curious@test.local' })];
|
|
180
|
+
case 1:
|
|
181
|
+
viewer = _c.sent();
|
|
182
|
+
testEnv.actAs(viewer);
|
|
183
|
+
_a = expect;
|
|
184
|
+
return [4 /*yield*/, requestAvatar('no-such-user')];
|
|
185
|
+
case 2:
|
|
186
|
+
_a.apply(void 0, [(_c.sent()).statusCode]).toBe(404);
|
|
187
|
+
_b = expect;
|
|
188
|
+
return [4 /*yield*/, requestAvatar('../../etc/passwd')];
|
|
189
|
+
case 3:
|
|
190
|
+
_b.apply(void 0, [(_c.sent()).statusCode]).toBe(404);
|
|
191
|
+
return [2 /*return*/];
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
}); });
|
|
195
|
+
it('401s without a logged-in session', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
196
|
+
var owner, png, response;
|
|
197
|
+
return __generator(this, function (_a) {
|
|
198
|
+
switch (_a.label) {
|
|
199
|
+
case 0: return [4 /*yield*/, testEnv.createUser({ name: 'Private', email: 'private@test.local' })];
|
|
200
|
+
case 1:
|
|
201
|
+
owner = _a.sent();
|
|
202
|
+
testEnv.actAs(owner);
|
|
203
|
+
return [4 /*yield*/, (0, sharp_1.default)({ create: { width: 32, height: 32, channels: 3, background: { r: 9, g: 9, b: 9 } } })
|
|
204
|
+
.png()
|
|
205
|
+
.toBuffer()];
|
|
206
|
+
case 2:
|
|
207
|
+
png = _a.sent();
|
|
208
|
+
return [4 /*yield*/, new UpdateUserInfo_1.UpdateUserInfo().updateAvatarPhoto(png.toString('base64'), 'image/png')];
|
|
209
|
+
case 3:
|
|
210
|
+
_a.sent();
|
|
211
|
+
testEnv.actAs(user_1.guestUser);
|
|
212
|
+
return [4 /*yield*/, requestAvatar(owner.id)];
|
|
213
|
+
case 4:
|
|
214
|
+
response = _a.sent();
|
|
215
|
+
expect(response.statusCode).toBe(401);
|
|
216
|
+
expect(response.body).not.toBeInstanceOf(Buffer);
|
|
217
|
+
return [2 /*return*/];
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
}); });
|
|
221
|
+
});
|
|
222
|
+
//# sourceMappingURL=avatarRoute.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatarRoute.test.js","sourceRoot":"","sources":["../../test/avatarRoute.test.ts"],"names":[],"mappings":"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"}
|