@proteinjs/user-server 1.16.1 → 1.18.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 +22 -0
- package/dist/generated/index.js +1 -1
- package/dist/generated/index.js.map +1 -1
- package/dist/src/routes/devLogin.d.ts +10 -0
- package/dist/src/routes/devLogin.d.ts.map +1 -1
- package/dist/src/routes/devLogin.js +28 -9
- package/dist/src/routes/devLogin.js.map +1 -1
- package/dist/src/services/Roles.d.ts +24 -1
- package/dist/src/services/Roles.d.ts.map +1 -1
- package/dist/src/services/Roles.js +92 -5
- package/dist/src/services/Roles.js.map +1 -1
- package/dist/src/services/UpdateUserInfo.d.ts +24 -1
- package/dist/src/services/UpdateUserInfo.d.ts.map +1 -1
- package/dist/src/services/UpdateUserInfo.js +79 -18
- package/dist/src/services/UpdateUserInfo.js.map +1 -1
- package/dist/test/DevLogin.test.js +13 -41
- package/dist/test/DevLogin.test.js.map +1 -1
- package/dist/test/DevLoginBootstrapAdmin.test.d.ts +2 -0
- package/dist/test/DevLoginBootstrapAdmin.test.d.ts.map +1 -0
- package/dist/test/DevLoginBootstrapAdmin.test.js +384 -0
- package/dist/test/DevLoginBootstrapAdmin.test.js.map +1 -0
- package/dist/test/MachineAccounts.integration.test.js.map +1 -1
- package/dist/test/Roles.integration.test.js +76 -0
- package/dist/test/Roles.integration.test.js.map +1 -1
- package/dist/test/UpdateUserInfoClearAvatarByAdmin.test.d.ts +2 -0
- package/dist/test/UpdateUserInfoClearAvatarByAdmin.test.d.ts.map +1 -0
- package/dist/test/UpdateUserInfoClearAvatarByAdmin.test.js +224 -0
- package/dist/test/UpdateUserInfoClearAvatarByAdmin.test.js.map +1 -0
- package/dist/test/UpdateUserInfoRefresh.test.d.ts +2 -0
- package/dist/test/UpdateUserInfoRefresh.test.d.ts.map +1 -0
- package/dist/test/UpdateUserInfoRefresh.test.js +99 -0
- package/dist/test/UpdateUserInfoRefresh.test.js.map +1 -0
- package/dist/test/devLoginHarness.d.ts +16 -0
- package/dist/test/devLoginHarness.d.ts.map +1 -0
- package/dist/test/devLoginHarness.js +79 -0
- package/dist/test/devLoginHarness.js.map +1 -0
- package/generated/index.ts +1 -1
- package/package.json +3 -3
- package/src/routes/devLogin.ts +17 -0
- package/src/services/Roles.ts +62 -5
- package/src/services/UpdateUserInfo.ts +68 -13
- package/test/DevLogin.test.ts +5 -36
- package/test/DevLoginBootstrapAdmin.test.ts +175 -0
- package/test/Roles.integration.test.ts +41 -0
- package/test/UpdateUserInfoClearAvatarByAdmin.test.ts +109 -0
- package/test/UpdateUserInfoRefresh.test.ts +40 -0
- package/test/devLoginHarness.ts +39 -0
|
@@ -6,12 +6,35 @@ import { Service } from '@proteinjs/service';
|
|
|
6
6
|
* audited: the role update and its `role_grant_event` row (actor, target, role, action; `created`
|
|
7
7
|
* is the timestamp) commit in one transaction, so the trail cannot diverge from the grants.
|
|
8
8
|
*
|
|
9
|
-
* Break-glass roles are never granted
|
|
9
|
+
* Break-glass roles are never granted through the service door — see `changeRole`; revoking one
|
|
10
|
+
* stays allowed. The ONE break-glass grant in code is `bootstrapAdmin`, the dev first-admin door
|
|
11
|
+
* (server-internal; reachable only through `/dev/login`'s gates, never over RPC).
|
|
12
|
+
*
|
|
13
|
+
* Nobody edits their OWN roles: separating 'roles' from 'users' means nothing if the holder can
|
|
14
|
+
* simply grant themselves more, and a self-revoke is the mirror hazard (the last holder locking
|
|
15
|
+
* themselves out). Both directions are refused — see `changeRole`; ask another user manager.
|
|
10
16
|
*/
|
|
11
17
|
export declare class Roles implements RolesService {
|
|
12
18
|
serviceMetadata: Service['serviceMetadata'];
|
|
13
19
|
grantRole(userId: string, role: string): Promise<void>;
|
|
14
20
|
revokeRole(userId: string, role: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* The dev first-admin door's grant — `/dev/login` honoring `DEV_BOOTSTRAP_ADMIN_EMAIL`
|
|
23
|
+
* (routes/devLogin.ts). A fresh dev database has no privileged account to grant from, and the
|
|
24
|
+
* only other path to break-glass is a manual UPDATE in Spanner Studio — right for prod and every
|
|
25
|
+
* clone-backed instance, wrong for a lane's throwaway estate on a real dev database, where raw
|
|
26
|
+
* writes are forbidden. So this grants 'admin' to `email`'s account exactly when NO account
|
|
27
|
+
* carries it yet (the membership test `UserAuth.hasRole` makes, over every row), audited like
|
|
28
|
+
* any grant — actor = the account itself, because the door acts for nobody else. Once an admin
|
|
29
|
+
* exists it never grants again: every later grant rides Admin → Users.
|
|
30
|
+
*
|
|
31
|
+
* Server-internal, like `Signup.createAccount`: absent from `RolesService`, so never
|
|
32
|
+
* RPC-reachable. The caller's two gates (DEVELOPMENT + DEV_AUTO_LOGIN_EMAIL) are the only way
|
|
33
|
+
* in, and test/prod never set the variable.
|
|
34
|
+
*/
|
|
35
|
+
bootstrapAdmin(email: string): Promise<'granted' | 'admin-exists' | 'no-account'>;
|
|
15
36
|
private changeRole;
|
|
37
|
+
/** Whether any account carries the break-glass role — `UserAuth.hasRole`'s membership test, over every row. */
|
|
38
|
+
private adminExists;
|
|
16
39
|
}
|
|
17
40
|
//# sourceMappingURL=Roles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Roles.d.ts","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAA8D,MAAM,iBAAiB,CAAC;AAE3G,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C
|
|
1
|
+
{"version":3,"file":"Roles.d.ts","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAA8D,MAAM,iBAAiB,CAAC;AAE3G,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C;;;;;;;;;;;;;GAaG;AACH,qBAAa,KAAM,YAAW,YAAY;IACjC,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAIhD;IAEI,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAItD,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7D;;;;;;;;;;;;;OAaG;IACG,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,cAAc,GAAG,YAAY,CAAC;YAqBzE,UAAU;IA8ExB,+GAA+G;YACjG,WAAW;CAK1B"}
|
|
@@ -55,7 +55,13 @@ var logger_1 = require("@proteinjs/logger");
|
|
|
55
55
|
* audited: the role update and its `role_grant_event` row (actor, target, role, action; `created`
|
|
56
56
|
* is the timestamp) commit in one transaction, so the trail cannot diverge from the grants.
|
|
57
57
|
*
|
|
58
|
-
* Break-glass roles are never granted
|
|
58
|
+
* Break-glass roles are never granted through the service door — see `changeRole`; revoking one
|
|
59
|
+
* stays allowed. The ONE break-glass grant in code is `bootstrapAdmin`, the dev first-admin door
|
|
60
|
+
* (server-internal; reachable only through `/dev/login`'s gates, never over RPC).
|
|
61
|
+
*
|
|
62
|
+
* Nobody edits their OWN roles: separating 'roles' from 'users' means nothing if the holder can
|
|
63
|
+
* simply grant themselves more, and a self-revoke is the mirror hazard (the last holder locking
|
|
64
|
+
* themselves out). Both directions are refused — see `changeRole`; ask another user manager.
|
|
59
65
|
*/
|
|
60
66
|
var Roles = /** @class */ (function () {
|
|
61
67
|
function Roles() {
|
|
@@ -89,10 +95,67 @@ var Roles = /** @class */ (function () {
|
|
|
89
95
|
});
|
|
90
96
|
});
|
|
91
97
|
};
|
|
98
|
+
/**
|
|
99
|
+
* The dev first-admin door's grant — `/dev/login` honoring `DEV_BOOTSTRAP_ADMIN_EMAIL`
|
|
100
|
+
* (routes/devLogin.ts). A fresh dev database has no privileged account to grant from, and the
|
|
101
|
+
* only other path to break-glass is a manual UPDATE in Spanner Studio — right for prod and every
|
|
102
|
+
* clone-backed instance, wrong for a lane's throwaway estate on a real dev database, where raw
|
|
103
|
+
* writes are forbidden. So this grants 'admin' to `email`'s account exactly when NO account
|
|
104
|
+
* carries it yet (the membership test `UserAuth.hasRole` makes, over every row), audited like
|
|
105
|
+
* any grant — actor = the account itself, because the door acts for nobody else. Once an admin
|
|
106
|
+
* exists it never grants again: every later grant rides Admin → Users.
|
|
107
|
+
*
|
|
108
|
+
* Server-internal, like `Signup.createAccount`: absent from `RolesService`, so never
|
|
109
|
+
* RPC-reachable. The caller's two gates (DEVELOPMENT + DEV_AUTO_LOGIN_EMAIL) are the only way
|
|
110
|
+
* in, and test/prod never set the variable.
|
|
111
|
+
*/
|
|
112
|
+
Roles.prototype.bootstrapAdmin = function (email) {
|
|
113
|
+
var _a;
|
|
114
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
115
|
+
var logger, db, user, roles;
|
|
116
|
+
var _this = this;
|
|
117
|
+
return __generator(this, function (_b) {
|
|
118
|
+
switch (_b.label) {
|
|
119
|
+
case 0:
|
|
120
|
+
logger = new logger_1.Logger({ name: 'Roles.bootstrapAdmin' });
|
|
121
|
+
db = (0, db_1.getDbAsSystem)();
|
|
122
|
+
return [4 /*yield*/, this.adminExists()];
|
|
123
|
+
case 1:
|
|
124
|
+
if (_b.sent()) {
|
|
125
|
+
return [2 /*return*/, 'admin-exists'];
|
|
126
|
+
}
|
|
127
|
+
return [4 /*yield*/, db.get(user_1.tables.User, { email: email.toLowerCase() })];
|
|
128
|
+
case 2:
|
|
129
|
+
user = _b.sent();
|
|
130
|
+
if (!user) {
|
|
131
|
+
return [2 /*return*/, 'no-account'];
|
|
132
|
+
}
|
|
133
|
+
roles = (_a = user.roles) !== null && _a !== void 0 ? _a : [];
|
|
134
|
+
return [4 /*yield*/, db.runTransaction(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
135
|
+
return __generator(this, function (_a) {
|
|
136
|
+
switch (_a.label) {
|
|
137
|
+
case 0: return [4 /*yield*/, db.update(user_1.tables.User, { id: user.id, roles: __spreadArray(__spreadArray([], roles, true), ['admin'], false) })];
|
|
138
|
+
case 1:
|
|
139
|
+
_a.sent();
|
|
140
|
+
return [4 /*yield*/, db.insert(user_1.tables.RoleGrantEvent, { actor: user.id, target: user.id, role: 'admin', action: 'grant' })];
|
|
141
|
+
case 2:
|
|
142
|
+
_a.sent();
|
|
143
|
+
return [2 /*return*/];
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}); })];
|
|
147
|
+
case 3:
|
|
148
|
+
_b.sent();
|
|
149
|
+
logger.info({ message: 'Break-glass admin granted by the dev first-admin door', obj: { target: user.id, email: email } });
|
|
150
|
+
return [2 /*return*/, 'granted'];
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
};
|
|
92
155
|
Roles.prototype.changeRole = function (userId, role, action) {
|
|
93
156
|
var _a;
|
|
94
157
|
return __awaiter(this, void 0, void 0, function () {
|
|
95
|
-
var logger, entry, db, user, roles, newRoles
|
|
158
|
+
var logger, entry, db, user, actor, roles, newRoles;
|
|
96
159
|
var _this = this;
|
|
97
160
|
return __generator(this, function (_b) {
|
|
98
161
|
switch (_b.label) {
|
|
@@ -104,8 +167,9 @@ var Roles = /** @class */ (function () {
|
|
|
104
167
|
}
|
|
105
168
|
// Break-glass passes every permission check, so no permission-mapped role — including
|
|
106
169
|
// 'roles' — may mint it: the only path to break-glass is a manual UPDATE on the user row
|
|
107
|
-
// in Spanner Studio, by a human, on purpose
|
|
108
|
-
// "held by nobody day-to-day"
|
|
170
|
+
// in Spanner Studio, by a human, on purpose (and, on a DEV server only, the first-admin door
|
|
171
|
+
// `bootstrapAdmin`). Revoke stays open: de-escalation toward "held by nobody day-to-day"
|
|
172
|
+
// should ride the audited path, not require database access.
|
|
109
173
|
if (entry.breakGlass && action === 'grant') {
|
|
110
174
|
throw new Error("'".concat(role, "' is a break-glass role \u2014 this service refuses to grant it. The only path to ") +
|
|
111
175
|
"break-glass is a manual UPDATE on the user row in Spanner Studio. (Revoking it here " +
|
|
@@ -133,13 +197,20 @@ var Roles = /** @class */ (function () {
|
|
|
133
197
|
throw new Error("'".concat(user.email, "' is a machine account: its roles are declared in code (its MachineAccount ") +
|
|
134
198
|
"declaration) and reverted to the declaration on every boot. Change the declaration instead.");
|
|
135
199
|
}
|
|
200
|
+
actor = new user_1.UserRepo().getUser();
|
|
201
|
+
// Nobody edits their own roles, in either direction. Checked BEFORE the no-change early
|
|
202
|
+
// return, so a self-target is always an error the caller sees rather than a silent no-op,
|
|
203
|
+
// and before the transaction, so a refused act leaves no audit row behind.
|
|
204
|
+
if (userId === actor.id) {
|
|
205
|
+
logger.warn({ message: 'Refused a self-targeted role change', obj: { actor: actor.id, role: role, action: action } });
|
|
206
|
+
throw new Error("You can't ".concat(action, " your own roles \u2014 ask another user manager."));
|
|
207
|
+
}
|
|
136
208
|
roles = (_a = user.roles) !== null && _a !== void 0 ? _a : [];
|
|
137
209
|
if (action === 'grant' ? roles.includes(role) : !roles.includes(role)) {
|
|
138
210
|
// No change, no audit row: the trail records what happened, not what was re-asked.
|
|
139
211
|
return [2 /*return*/];
|
|
140
212
|
}
|
|
141
213
|
newRoles = action === 'grant' ? __spreadArray(__spreadArray([], roles, true), [role], false) : roles.filter(function (heldRole) { return heldRole !== role; });
|
|
142
|
-
actor = new user_1.UserRepo().getUser();
|
|
143
214
|
return [4 /*yield*/, db.runTransaction(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
144
215
|
return __generator(this, function (_a) {
|
|
145
216
|
switch (_a.label) {
|
|
@@ -169,6 +240,22 @@ var Roles = /** @class */ (function () {
|
|
|
169
240
|
});
|
|
170
241
|
});
|
|
171
242
|
};
|
|
243
|
+
/** Whether any account carries the break-glass role — `UserAuth.hasRole`'s membership test, over every row. */
|
|
244
|
+
Roles.prototype.adminExists = function () {
|
|
245
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
246
|
+
var qb, users;
|
|
247
|
+
return __generator(this, function (_a) {
|
|
248
|
+
switch (_a.label) {
|
|
249
|
+
case 0:
|
|
250
|
+
qb = new db_1.QueryBuilderFactory().getQueryBuilder(user_1.tables.User).select({ fields: ['id', 'roles'] });
|
|
251
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().query(user_1.tables.User, qb)];
|
|
252
|
+
case 1:
|
|
253
|
+
users = _a.sent();
|
|
254
|
+
return [2 /*return*/, users.some(function (user) { var _a; return ((_a = user.roles) !== null && _a !== void 0 ? _a : []).includes('admin'); })];
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
};
|
|
172
259
|
return Roles;
|
|
173
260
|
}());
|
|
174
261
|
exports.Roles = Roles;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Roles.js","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"Roles.js","sourceRoot":"","sources":["../../../src/services/Roles.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,12 +24,22 @@ export declare class UpdateUserInfo implements UpdateUserInfoService {
|
|
|
24
24
|
updatePassword(currentPassword: string, newPassword: string): Promise<UpdatePasswordResponse>;
|
|
25
25
|
updateAvatarPhoto(fileData: string, mimeType: string, crop?: AvatarCrop): Promise<UpdatedUser>;
|
|
26
26
|
updateAvatarEmoji(emoji: string): Promise<UpdatedUser>;
|
|
27
|
-
clearAvatar(): Promise<UpdatedUser>;
|
|
27
|
+
clearAvatar(userId?: string): Promise<UpdatedUser>;
|
|
28
|
+
/**
|
|
29
|
+
* The read-only half of `saveUserInfo`: no write, just the stored row pulled back into the
|
|
30
|
+
* session cache. Every mutation through this service already refreshes the cache, so this is
|
|
31
|
+
* for changes made ELSEWHERE — another device, another tab, a user manager — which the cached
|
|
32
|
+
* user would otherwise keep hiding until the next sign-in.
|
|
33
|
+
*/
|
|
34
|
+
refresh(): Promise<UpdatedUser>;
|
|
28
35
|
/**
|
|
29
36
|
* The single door to the avatar columns — every mutation assigns BOTH, which is what enforces
|
|
30
37
|
* the exactly-one-active invariant (photo OR emoji, never both). Also the previous photo's
|
|
31
38
|
* cleanup point: an avatar file the user row no longer points to is unreachable (the /avatar
|
|
32
39
|
* route serves only the id on the user row), so it is deleted here, after the row moves off it.
|
|
40
|
+
*
|
|
41
|
+
* `userId` names ANOTHER person (see {@link resolveTarget} for the permission that admits it);
|
|
42
|
+
* everything below then applies to that person's row and their previous photo.
|
|
33
43
|
*/
|
|
34
44
|
private setAvatar;
|
|
35
45
|
/**
|
|
@@ -39,8 +49,21 @@ export declare class UpdateUserInfo implements UpdateUserInfoService {
|
|
|
39
49
|
* long-lived contexts that keep their session data (sockets) — serving the STALE user until
|
|
40
50
|
* re-login (the rename wart). Fusing persist + refresh here means no future mutation can
|
|
41
51
|
* reintroduce that class of staleness.
|
|
52
|
+
*
|
|
53
|
+
* The refresh is the CALLER's own cache, so it happens only when the caller is the target. A
|
|
54
|
+
* user manager changing someone else writes the row and stops there: refreshing would hand the
|
|
55
|
+
* admin the target's row as their own identity, and there is no way to reach the target's
|
|
56
|
+
* session from here anyway — their next sign-in reads the row.
|
|
42
57
|
*/
|
|
43
58
|
private saveUserInfo;
|
|
59
|
+
/**
|
|
60
|
+
* The user a mutation targets, and whether that is the caller.
|
|
61
|
+
*
|
|
62
|
+
* The service door is `allUsers` — it has to be, every signed-in user manages their own
|
|
63
|
+
* profile through it — so naming ANOTHER person's id is authorized here, in-body and
|
|
64
|
+
* fail-closed: only a `users` permission holder may do it.
|
|
65
|
+
*/
|
|
66
|
+
private resolveTarget;
|
|
44
67
|
/**
|
|
45
68
|
* THE avatar image pipeline — the only place avatar pixels are ever resampled: decode,
|
|
46
69
|
* auto-orient from EXIF, extract the crop frame (client-framed, or the centered square),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateUserInfo.d.ts","sourceRoot":"","sources":["../../../src/services/UpdateUserInfo.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"UpdateUserInfo.d.ts","sourceRoot":"","sources":["../../../src/services/UpdateUserInfo.ts"],"names":[],"mappings":"AAIA,OAAO,EAML,sBAAsB,EACtB,WAAW,EACX,qBAAqB,EACrB,UAAU,EAEX,MAAM,iBAAiB,CAAC;AAIzB,qBAAa,cAAe,YAAW,qBAAqB;IAC1D;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAO;IAC9C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAM;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAoB;IAClE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAMhD;IACF,mGAAmG;IACnG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAM;IACrD,mGAAmG;IACnG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAiF;IAE/G,eAAe;;;;MAIpB;IAEI,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAI9C,cAAc,CAAC,eAAe,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAkD7F,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAoB9F,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IActD,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAIxD;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,WAAW,CAAC;IAQrC;;;;;;;;OAQG;YACW,SAAS;IAoBvB;;;;;;;;;;;;OAYG;YACW,YAAY;IAc1B;;;;;;OAMG;IACH,OAAO,CAAC,aAAa;IAWrB;;;;;;;;;;;OAWG;YACW,YAAY;IAe1B;;;;OAIG;YACW,kBAAkB;IAahC;;;;OAIG;IACH,OAAO,CAAC,SAAS;YAmBH,UAAU;CAMzB"}
|
|
@@ -180,38 +180,76 @@ var UpdateUserInfo = /** @class */ (function () {
|
|
|
180
180
|
});
|
|
181
181
|
});
|
|
182
182
|
};
|
|
183
|
-
UpdateUserInfo.prototype.clearAvatar = function () {
|
|
183
|
+
UpdateUserInfo.prototype.clearAvatar = function (userId) {
|
|
184
184
|
return __awaiter(this, void 0, void 0, function () {
|
|
185
185
|
return __generator(this, function (_a) {
|
|
186
186
|
switch (_a.label) {
|
|
187
|
-
case 0: return [4 /*yield*/, this.setAvatar({ avatarEmoji: null, avatarFileId: null })];
|
|
187
|
+
case 0: return [4 /*yield*/, this.setAvatar({ avatarEmoji: null, avatarFileId: null }, userId)];
|
|
188
188
|
case 1: return [2 /*return*/, _a.sent()];
|
|
189
189
|
}
|
|
190
190
|
});
|
|
191
191
|
});
|
|
192
192
|
};
|
|
193
|
+
/**
|
|
194
|
+
* The read-only half of `saveUserInfo`: no write, just the stored row pulled back into the
|
|
195
|
+
* session cache. Every mutation through this service already refreshes the cache, so this is
|
|
196
|
+
* for changes made ELSEWHERE — another device, another tab, a user manager — which the cached
|
|
197
|
+
* user would otherwise keep hiding until the next sign-in.
|
|
198
|
+
*/
|
|
199
|
+
UpdateUserInfo.prototype.refresh = function () {
|
|
200
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
201
|
+
var userRepo, updated;
|
|
202
|
+
return __generator(this, function (_a) {
|
|
203
|
+
switch (_a.label) {
|
|
204
|
+
case 0:
|
|
205
|
+
userRepo = new user_1.UserRepo();
|
|
206
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(user_1.tables.User, { id: userRepo.getUser().id })];
|
|
207
|
+
case 1:
|
|
208
|
+
updated = _a.sent();
|
|
209
|
+
delete updated.password; // the same password-less shape userCache caches
|
|
210
|
+
userRepo.setUser(updated);
|
|
211
|
+
return [2 /*return*/, updated];
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
};
|
|
193
216
|
/**
|
|
194
217
|
* The single door to the avatar columns — every mutation assigns BOTH, which is what enforces
|
|
195
218
|
* the exactly-one-active invariant (photo OR emoji, never both). Also the previous photo's
|
|
196
219
|
* cleanup point: an avatar file the user row no longer points to is unreachable (the /avatar
|
|
197
220
|
* route serves only the id on the user row), so it is deleted here, after the row moves off it.
|
|
221
|
+
*
|
|
222
|
+
* `userId` names ANOTHER person (see {@link resolveTarget} for the permission that admits it);
|
|
223
|
+
* everything below then applies to that person's row and their previous photo.
|
|
198
224
|
*/
|
|
199
|
-
UpdateUserInfo.prototype.setAvatar = function (avatar) {
|
|
225
|
+
UpdateUserInfo.prototype.setAvatar = function (avatar, userId) {
|
|
200
226
|
return __awaiter(this, void 0, void 0, function () {
|
|
201
|
-
var
|
|
227
|
+
var targetUserId, previousAvatarFileId, updated;
|
|
202
228
|
return __generator(this, function (_a) {
|
|
203
229
|
switch (_a.label) {
|
|
204
230
|
case 0:
|
|
205
|
-
|
|
206
|
-
return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(user_1.tables.User, { id:
|
|
231
|
+
targetUserId = this.resolveTarget(userId).targetUserId;
|
|
232
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(user_1.tables.User, { id: targetUserId })];
|
|
207
233
|
case 1:
|
|
208
234
|
previousAvatarFileId = (_a.sent()).avatarFileId;
|
|
209
|
-
return [4 /*yield*/, this.saveUserInfo(avatar)];
|
|
235
|
+
return [4 /*yield*/, this.saveUserInfo(avatar, userId)];
|
|
210
236
|
case 2:
|
|
211
237
|
updated = _a.sent();
|
|
212
238
|
if (!(previousAvatarFileId && previousAvatarFileId !== avatar.avatarFileId)) return [3 /*break*/, 4];
|
|
213
|
-
|
|
239
|
+
// Deleted as SYSTEM, like the user-row write it accompanies: the file lives in the TARGET's
|
|
240
|
+
// scope, and a caller-scoped delete (`FileStorage.deleteFile`) would silently match nothing
|
|
241
|
+
// when a user manager clears someone else's photo, orphaning the bytes. This door has
|
|
242
|
+
// already made its own access decision, the same shape as the /avatar route's system read.
|
|
243
|
+
// The bytes still die with the row — `FileStorageTableWatcher` fires for every file-row
|
|
244
|
+
// delete path, system sweeps included.
|
|
245
|
+
return [4 /*yield*/, (0, user_1.getScopedDbAsSystem)().delete(db_file_1.tables.File, { id: previousAvatarFileId })];
|
|
214
246
|
case 3:
|
|
247
|
+
// Deleted as SYSTEM, like the user-row write it accompanies: the file lives in the TARGET's
|
|
248
|
+
// scope, and a caller-scoped delete (`FileStorage.deleteFile`) would silently match nothing
|
|
249
|
+
// when a user manager clears someone else's photo, orphaning the bytes. This door has
|
|
250
|
+
// already made its own access decision, the same shape as the /avatar route's system read.
|
|
251
|
+
// The bytes still die with the row — `FileStorageTableWatcher` fires for every file-row
|
|
252
|
+
// delete path, system sweeps included.
|
|
215
253
|
_a.sent();
|
|
216
254
|
_a.label = 4;
|
|
217
255
|
case 4: return [2 /*return*/, updated];
|
|
@@ -226,29 +264,52 @@ var UpdateUserInfo = /** @class */ (function () {
|
|
|
226
264
|
* long-lived contexts that keep their session data (sockets) — serving the STALE user until
|
|
227
265
|
* re-login (the rename wart). Fusing persist + refresh here means no future mutation can
|
|
228
266
|
* reintroduce that class of staleness.
|
|
267
|
+
*
|
|
268
|
+
* The refresh is the CALLER's own cache, so it happens only when the caller is the target. A
|
|
269
|
+
* user manager changing someone else writes the row and stops there: refreshing would hand the
|
|
270
|
+
* admin the target's row as their own identity, and there is no way to reach the target's
|
|
271
|
+
* session from here anyway — their next sign-in reads the row.
|
|
229
272
|
*/
|
|
230
|
-
UpdateUserInfo.prototype.saveUserInfo = function (changes) {
|
|
273
|
+
UpdateUserInfo.prototype.saveUserInfo = function (changes, userId) {
|
|
231
274
|
return __awaiter(this, void 0, void 0, function () {
|
|
232
|
-
var userRepo,
|
|
233
|
-
return __generator(this, function (
|
|
234
|
-
switch (
|
|
275
|
+
var userRepo, _a, targetUserId, targetIsCaller, db, updated;
|
|
276
|
+
return __generator(this, function (_b) {
|
|
277
|
+
switch (_b.label) {
|
|
235
278
|
case 0:
|
|
236
279
|
userRepo = new user_1.UserRepo();
|
|
237
|
-
|
|
280
|
+
_a = this.resolveTarget(userId), targetUserId = _a.targetUserId, targetIsCaller = _a.targetIsCaller;
|
|
238
281
|
db = (0, db_1.getDbAsSystem)();
|
|
239
|
-
return [4 /*yield*/, db.update(user_1.tables.User, changes, { id:
|
|
282
|
+
return [4 /*yield*/, db.update(user_1.tables.User, changes, { id: targetUserId })];
|
|
240
283
|
case 1:
|
|
241
|
-
|
|
242
|
-
return [4 /*yield*/, db.get(user_1.tables.User, { id:
|
|
284
|
+
_b.sent();
|
|
285
|
+
return [4 /*yield*/, db.get(user_1.tables.User, { id: targetUserId })];
|
|
243
286
|
case 2:
|
|
244
|
-
updated =
|
|
287
|
+
updated = _b.sent();
|
|
245
288
|
delete updated.password; // the same password-less shape userCache caches
|
|
246
|
-
|
|
289
|
+
if (targetIsCaller) {
|
|
290
|
+
userRepo.setUser(updated);
|
|
291
|
+
}
|
|
247
292
|
return [2 /*return*/, updated];
|
|
248
293
|
}
|
|
249
294
|
});
|
|
250
295
|
});
|
|
251
296
|
};
|
|
297
|
+
/**
|
|
298
|
+
* The user a mutation targets, and whether that is the caller.
|
|
299
|
+
*
|
|
300
|
+
* The service door is `allUsers` — it has to be, every signed-in user manages their own
|
|
301
|
+
* profile through it — so naming ANOTHER person's id is authorized here, in-body and
|
|
302
|
+
* fail-closed: only a `users` permission holder may do it.
|
|
303
|
+
*/
|
|
304
|
+
UpdateUserInfo.prototype.resolveTarget = function (userId) {
|
|
305
|
+
var callerId = new user_1.UserRepo().getUser().id;
|
|
306
|
+
var targetUserId = userId !== null && userId !== void 0 ? userId : callerId;
|
|
307
|
+
var targetIsCaller = targetUserId === callerId;
|
|
308
|
+
if (!targetIsCaller && !user_1.UserAuth.hasPermission(user_1.USER_PERMISSIONS.users)) {
|
|
309
|
+
throw new Error("Only a user manager can change another person's avatar.");
|
|
310
|
+
}
|
|
311
|
+
return { targetUserId: targetUserId, targetIsCaller: targetIsCaller };
|
|
312
|
+
};
|
|
252
313
|
/**
|
|
253
314
|
* THE avatar image pipeline — the only place avatar pixels are ever resampled: decode,
|
|
254
315
|
* auto-orient from EXIF, extract the crop frame (client-framed, or the centered square),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UpdateUserInfo.js","sourceRoot":"","sources":["../../../src/services/UpdateUserInfo.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,gDAA0B;AAC1B,4DAAqC;AACrC,oCAA8C;AAC9C,
|
|
1
|
+
{"version":3,"file":"UpdateUserInfo.js","sourceRoot":"","sources":["../../../src/services/UpdateUserInfo.ts"],"names":[],"mappings":"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"}
|
|
@@ -39,8 +39,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
39
39
|
var db_1 = require("@proteinjs/db");
|
|
40
40
|
var user_1 = require("@proteinjs/user");
|
|
41
41
|
var PasswordHasher_1 = require("../src/authentication/PasswordHasher");
|
|
42
|
-
var
|
|
43
|
-
var passportSessionHarness_1 = require("./passportSessionHarness");
|
|
42
|
+
var devLoginHarness_1 = require("./devLoginHarness");
|
|
44
43
|
var UserServerTestEnvironment_1 = require("./UserServerTestEnvironment");
|
|
45
44
|
var testEnv = new UserServerTestEnvironment_1.UserServerTestEnvironment();
|
|
46
45
|
/**
|
|
@@ -51,39 +50,10 @@ var testEnv = new UserServerTestEnvironment_1.UserServerTestEnvironment();
|
|
|
51
50
|
* - Double gate: `DEVELOPMENT` AND `DEV_AUTO_LOGIN_EMAIL` both present, else 404 (unchanged).
|
|
52
51
|
* - Domain rail: a `?email=` param must share `DEV_AUTO_LOGIN_EMAIL`'s domain — even a dev server
|
|
53
52
|
* must not mint sessions (much less accounts) for arbitrary domains. Others 400.
|
|
53
|
+
* The first-admin door (`DEV_BOOTSTRAP_ADMIN_EMAIL`) has its own suite, DevLoginBootstrapAdmin.test.ts;
|
|
54
|
+
* here the variable is unset, so every created account is role-less.
|
|
54
55
|
*/
|
|
55
56
|
var ENV_EMAIL = 'dev@test.local';
|
|
56
|
-
var invokeDevLogin = function (query) { return __awaiter(void 0, void 0, void 0, function () {
|
|
57
|
-
var _a, request, events, outcome, response;
|
|
58
|
-
var _b;
|
|
59
|
-
return __generator(this, function (_c) {
|
|
60
|
-
switch (_c.label) {
|
|
61
|
-
case 0: return [4 /*yield*/, (0, passportSessionHarness_1.createPassportRequest)({ query: query })];
|
|
62
|
-
case 1:
|
|
63
|
-
_a = _c.sent(), request = _a.request, events = _a.events;
|
|
64
|
-
outcome = { sessionRegenerated: false, sessionSaved: false };
|
|
65
|
-
response = {
|
|
66
|
-
status: function (code) {
|
|
67
|
-
outcome.status = code;
|
|
68
|
-
return this;
|
|
69
|
-
},
|
|
70
|
-
send: function (body) {
|
|
71
|
-
outcome.body = body;
|
|
72
|
-
},
|
|
73
|
-
redirect: function (path) {
|
|
74
|
-
outcome.redirect = path;
|
|
75
|
-
},
|
|
76
|
-
};
|
|
77
|
-
return [4 /*yield*/, devLogin_1.devLogin.onRequest(request, response)];
|
|
78
|
-
case 2:
|
|
79
|
-
_c.sent();
|
|
80
|
-
outcome.loggedInAs = (_b = request.session.passport) === null || _b === void 0 ? void 0 : _b.user;
|
|
81
|
-
outcome.sessionRegenerated = events.includes('regenerate');
|
|
82
|
-
outcome.sessionSaved = events.includes('save');
|
|
83
|
-
return [2 /*return*/, outcome];
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}); };
|
|
87
57
|
var getUserRow = function (email) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
88
58
|
switch (_a.label) {
|
|
89
59
|
case 0: return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(user_1.tables.User, { email: email })];
|
|
@@ -94,6 +64,7 @@ describe('devLogin route', function () {
|
|
|
94
64
|
var originalEnv = {
|
|
95
65
|
DEVELOPMENT: process.env.DEVELOPMENT,
|
|
96
66
|
DEV_AUTO_LOGIN_EMAIL: process.env.DEV_AUTO_LOGIN_EMAIL,
|
|
67
|
+
DEV_BOOTSTRAP_ADMIN_EMAIL: process.env.DEV_BOOTSTRAP_ADMIN_EMAIL,
|
|
97
68
|
};
|
|
98
69
|
beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
99
70
|
return __generator(this, function (_a) {
|
|
@@ -118,6 +89,7 @@ describe('devLogin route', function () {
|
|
|
118
89
|
beforeEach(function () {
|
|
119
90
|
process.env.DEVELOPMENT = 'true';
|
|
120
91
|
process.env.DEV_AUTO_LOGIN_EMAIL = ENV_EMAIL;
|
|
92
|
+
delete process.env.DEV_BOOTSTRAP_ADMIN_EMAIL;
|
|
121
93
|
});
|
|
122
94
|
afterEach(function () {
|
|
123
95
|
for (var _i = 0, _a = Object.entries(originalEnv); _i < _a.length; _i++) {
|
|
@@ -137,7 +109,7 @@ describe('devLogin route', function () {
|
|
|
137
109
|
case 0: return [4 /*yield*/, testEnv.createUser({ name: 'Dev Default', email: ENV_EMAIL })];
|
|
138
110
|
case 1:
|
|
139
111
|
_a.sent();
|
|
140
|
-
return [4 /*yield*/, invokeDevLogin()];
|
|
112
|
+
return [4 /*yield*/, (0, devLoginHarness_1.invokeDevLogin)()];
|
|
141
113
|
case 2:
|
|
142
114
|
outcome = _a.sent();
|
|
143
115
|
expect(outcome.loggedInAs).toBe(ENV_EMAIL);
|
|
@@ -156,7 +128,7 @@ describe('devLogin route', function () {
|
|
|
156
128
|
case 0: return [4 /*yield*/, testEnv.createUser({ name: 'Agent Two', email: 'agent2@test.local' })];
|
|
157
129
|
case 1:
|
|
158
130
|
_a.sent();
|
|
159
|
-
return [4 /*yield*/, invokeDevLogin({ email: 'agent2@test.local' })];
|
|
131
|
+
return [4 /*yield*/, (0, devLoginHarness_1.invokeDevLogin)({ email: 'agent2@test.local' })];
|
|
160
132
|
case 2:
|
|
161
133
|
outcome = _a.sent();
|
|
162
134
|
expect(outcome.loggedInAs).toBe('agent2@test.local');
|
|
@@ -175,7 +147,7 @@ describe('devLogin route', function () {
|
|
|
175
147
|
return [4 /*yield*/, getUserRow('agent3@test.local')];
|
|
176
148
|
case 1:
|
|
177
149
|
_a.apply(void 0, [_c.sent()]).toBeUndefined();
|
|
178
|
-
return [4 /*yield*/, invokeDevLogin({ email: 'agent3@test.local' })];
|
|
150
|
+
return [4 /*yield*/, (0, devLoginHarness_1.invokeDevLogin)({ email: 'agent3@test.local' })];
|
|
179
151
|
case 2:
|
|
180
152
|
outcome = _c.sent();
|
|
181
153
|
expect(outcome.loggedInAs).toBe('agent3@test.local');
|
|
@@ -200,7 +172,7 @@ describe('devLogin route', function () {
|
|
|
200
172
|
var outcome, _a;
|
|
201
173
|
return __generator(this, function (_b) {
|
|
202
174
|
switch (_b.label) {
|
|
203
|
-
case 0: return [4 /*yield*/, invokeDevLogin({ email: 'intruder@evil.example' })];
|
|
175
|
+
case 0: return [4 /*yield*/, (0, devLoginHarness_1.invokeDevLogin)({ email: 'intruder@evil.example' })];
|
|
204
176
|
case 1:
|
|
205
177
|
outcome = _b.sent();
|
|
206
178
|
expect(outcome.status).toBe(400);
|
|
@@ -221,7 +193,7 @@ describe('devLogin route', function () {
|
|
|
221
193
|
switch (_b.label) {
|
|
222
194
|
case 0:
|
|
223
195
|
malformed = 'brent shareproof-a@test.local';
|
|
224
|
-
return [4 /*yield*/, invokeDevLogin({ email: malformed })];
|
|
196
|
+
return [4 /*yield*/, (0, devLoginHarness_1.invokeDevLogin)({ email: malformed })];
|
|
225
197
|
case 1:
|
|
226
198
|
outcome = _b.sent();
|
|
227
199
|
expect(outcome.status).toBe(400);
|
|
@@ -242,7 +214,7 @@ describe('devLogin route', function () {
|
|
|
242
214
|
var outcome, _a;
|
|
243
215
|
return __generator(this, function (_b) {
|
|
244
216
|
switch (_b.label) {
|
|
245
|
-
case 0: return [4 /*yield*/, invokeDevLogin({ email: 'agent6+lane-a@test.local' })];
|
|
217
|
+
case 0: return [4 /*yield*/, (0, devLoginHarness_1.invokeDevLogin)({ email: 'agent6+lane-a@test.local' })];
|
|
246
218
|
case 1:
|
|
247
219
|
outcome = _b.sent();
|
|
248
220
|
expect(outcome.loggedInAs).toBe('agent6+lane-a@test.local');
|
|
@@ -262,7 +234,7 @@ describe('devLogin route', function () {
|
|
|
262
234
|
switch (_b.label) {
|
|
263
235
|
case 0:
|
|
264
236
|
delete process.env.DEVELOPMENT;
|
|
265
|
-
return [4 /*yield*/, invokeDevLogin({ email: 'agent4@test.local' })];
|
|
237
|
+
return [4 /*yield*/, (0, devLoginHarness_1.invokeDevLogin)({ email: 'agent4@test.local' })];
|
|
266
238
|
case 1:
|
|
267
239
|
outcome = _b.sent();
|
|
268
240
|
expect(outcome.status).toBe(404);
|
|
@@ -281,7 +253,7 @@ describe('devLogin route', function () {
|
|
|
281
253
|
switch (_b.label) {
|
|
282
254
|
case 0:
|
|
283
255
|
delete process.env.DEV_AUTO_LOGIN_EMAIL;
|
|
284
|
-
return [4 /*yield*/, invokeDevLogin({ email: 'agent5@test.local' })];
|
|
256
|
+
return [4 /*yield*/, (0, devLoginHarness_1.invokeDevLogin)({ email: 'agent5@test.local' })];
|
|
285
257
|
case 1:
|
|
286
258
|
outcome = _b.sent();
|
|
287
259
|
expect(outcome.status).toBe(404);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DevLogin.test.js","sourceRoot":"","sources":["../../test/DevLogin.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,oCAA8C;AAC9C,wCAAyC;AACzC,uEAAsE;AACtE,
|
|
1
|
+
{"version":3,"file":"DevLogin.test.js","sourceRoot":"","sources":["../../test/DevLogin.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DevLoginBootstrapAdmin.test.d.ts","sourceRoot":"","sources":["../../test/DevLoginBootstrapAdmin.test.ts"],"names":[],"mappings":""}
|