@proteinjs/user-server 1.10.4 → 1.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/CHANGELOG.md +22 -0
- package/dist/src/services/Signup.js +1 -1
- package/dist/src/services/Signup.js.map +1 -1
- package/dist/test/AccessGrantPrincipalReference.integration.test.d.ts +2 -0
- package/dist/test/AccessGrantPrincipalReference.integration.test.d.ts.map +1 -0
- package/dist/test/AccessGrantPrincipalReference.integration.test.js +219 -0
- package/dist/test/AccessGrantPrincipalReference.integration.test.js.map +1 -0
- package/dist/test/SignupInvite.test.js +7 -4
- package/dist/test/SignupInvite.test.js.map +1 -1
- package/dist/test/SignupRoute.test.js +12 -8
- package/dist/test/SignupRoute.test.js.map +1 -1
- package/package.json +3 -3
- package/src/services/Signup.ts +2 -2
- package/test/AccessGrantPrincipalReference.integration.test.ts +132 -0
- package/test/SignupInvite.test.ts +3 -1
- package/test/SignupRoute.test.ts +6 -3
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,28 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.11.1](https://github.com/proteinjs/user/compare/@proteinjs/user-server@1.11.0...@proteinjs/user-server@1.11.1) (2026-08-29)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* AccessGrant.principal names its reference table 'user', not the class name — UserTable.name is the class's static JS name ('UserTable'), which deserialize stamped onto every read-back principal, so principal.get() threw (Unable to find table: UserTable) and the admin grant table could never render principals as linked names. Stored cells are bare ids — verified against the live emulator (the raw principal cell is exactly the user id; nothing 'UserTable'-shaped in the row) — so the fix is declaration-only: zero data touched, zero DDL (same STRING(36) column). Tests: user-server emulator suite (stored-bare-id premise, read-back principal resolves the user record, admin/owner insert-gate id-equality pin) + user-ui admin grant-table linked-name rendering bound over the real declaration (the adminInvitedByRendering pattern). Red-before-green: the resolution and rendering legs fail at the pre-fix declaration ('UserTable' stamped on the reference; link at ?table=UserTable). ([037f3ef](https://github.com/proteinjs/user/commit/037f3efd316b56d557c044639f7cd8e044e7d313))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# [1.11.0](https://github.com/proteinjs/user/compare/@proteinjs/user-server@1.10.4...@proteinjs/user-server@1.11.0) (2026-08-29)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* invitedBy is a real user reference on the user and invite tables — retyped IN PLACE via ReferenceColumn width adoption (db 1.37.0's maxLength option at the column's original 255 width; a reference stores the same id bytes, so deployed rows read back unchanged and the schema sync sees zero DDL — verified against the emulator in @proteinjs/db-driver-spanner's ReferenceColumnAdoptWidth suite). Writers stamp references: sendInvite mints Reference(user, inviter id), createUser carries the invite's reference onto the new account (devLogin's null unchanged); the purge contract holds — a purged inviter leaves the reference dangling, which IS the pseudonymization. Admin payoff: the generic Users/Invites record tables render the inviter as their linked NAME via db-ui's ReferenceCellValue — bound over the real table declarations by the new user-ui suite. Floors: @proteinjs/db ^1.37.0 (user), @proteinjs/db-ui ^1.13.0 (ui); user-ui's jest config adopts the estate singleton pin user-server carries (CI-inert) ([1c5f32a](https://github.com/proteinjs/user/commit/1c5f32a2603f27c41e39e4cfc07f1c3ff17af827))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
## [1.10.4](https://github.com/proteinjs/user/compare/@proteinjs/user-server@1.10.3...@proteinjs/user-server@1.10.4) (2026-08-28)
|
|
7
29
|
|
|
8
30
|
**Note:** Version bump only for package @proteinjs/user-server
|
|
@@ -196,7 +196,7 @@ var Signup = /** @class */ (function () {
|
|
|
196
196
|
email: caseInsensitiveEmail,
|
|
197
197
|
token: token,
|
|
198
198
|
tokenExpiresAt: tokenExpiresAt,
|
|
199
|
-
invitedBy: userId,
|
|
199
|
+
invitedBy: new db_1.Reference(user_1.tables.User.name, userId),
|
|
200
200
|
})];
|
|
201
201
|
case 6:
|
|
202
202
|
invite = _c.sent();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Signup.js","sourceRoot":"","sources":["../../../src/services/Signup.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
|
1
|
+
{"version":3,"file":"Signup.js","sourceRoot":"","sources":["../../../src/services/Signup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessGrantPrincipalReference.integration.test.d.ts","sourceRoot":"","sources":["../../test/AccessGrantPrincipalReference.integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,219 @@
|
|
|
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 reflection_1 = require("@proteinjs/reflection");
|
|
41
|
+
var user_1 = require("@proteinjs/user");
|
|
42
|
+
var UserServerTestEnvironment_1 = require("./UserServerTestEnvironment");
|
|
43
|
+
var testEnv = new UserServerTestEnvironment_1.UserServerTestEnvironment();
|
|
44
|
+
var objectCache = function () { return reflection_1.SourceRepository.get().objectCache; };
|
|
45
|
+
/**
|
|
46
|
+
* AccessGrant.principal is a REFERENCE to the `user` table (the 2026-08 declaration bug: the
|
|
47
|
+
* column named its reference table `UserTable.name` — the class's static JS name, `'UserTable'` —
|
|
48
|
+
* not the table's declared name `'user'`).
|
|
49
|
+
*
|
|
50
|
+
* PREMISE (why the fix is declaration-only): `ReferenceColumn.serialize` stores the bare id —
|
|
51
|
+
* the reference's table name lives ONLY in the column declaration, which `deserialize` stamps
|
|
52
|
+
* onto every read-back `Reference`. The first test asserts that against the live emulator: the
|
|
53
|
+
* raw stored `principal` cell is exactly the principal's user id. Zero data is touched by the
|
|
54
|
+
* fix and the schema sync sees no change (same STRING(36) column either way).
|
|
55
|
+
*
|
|
56
|
+
* SURFACE: `grant.principal.get()` resolves through `tableByName(reference._table)` — with the
|
|
57
|
+
* class name stamped on it, resolution throws `Unable to find table: UserTable`, so the admin
|
|
58
|
+
* grant table could never render principals as linked names (db-ui's ReferenceCellValue rides
|
|
59
|
+
* this same `Reference.get()`; the ui-package suite binds that rendering surface).
|
|
60
|
+
*
|
|
61
|
+
* NON-REGRESSION: the grant machinery itself compares stored PRINCIPAL IDS, never the
|
|
62
|
+
* declaration's table name — the admin/owner insert gate must behave identically before and
|
|
63
|
+
* after the fix (pinned by the caller-context legs).
|
|
64
|
+
*/
|
|
65
|
+
describe('AccessGrant.principal reference — stored bare ids; declaration resolves the user table', function () {
|
|
66
|
+
var alice;
|
|
67
|
+
var admin;
|
|
68
|
+
var stranger;
|
|
69
|
+
beforeAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
70
|
+
return __generator(this, function (_a) {
|
|
71
|
+
switch (_a.label) {
|
|
72
|
+
case 0: return [4 /*yield*/, testEnv.beforeAll()];
|
|
73
|
+
case 1:
|
|
74
|
+
_a.sent();
|
|
75
|
+
// Reference.get() resolves tables by NAME off the source graph (not loaded in tests) —
|
|
76
|
+
// register exactly this package's tables, as the app's composition would.
|
|
77
|
+
objectCache()['@proteinjs/db/Table'] = Object.values(user_1.tables);
|
|
78
|
+
return [2 /*return*/];
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}); }, 120000);
|
|
82
|
+
afterAll(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
83
|
+
return __generator(this, function (_a) {
|
|
84
|
+
switch (_a.label) {
|
|
85
|
+
case 0:
|
|
86
|
+
delete objectCache()['@proteinjs/db/Table'];
|
|
87
|
+
return [4 /*yield*/, testEnv.afterAll()];
|
|
88
|
+
case 1:
|
|
89
|
+
_a.sent();
|
|
90
|
+
return [2 /*return*/];
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}); }, 60000);
|
|
94
|
+
beforeEach(function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
95
|
+
var db;
|
|
96
|
+
return __generator(this, function (_a) {
|
|
97
|
+
switch (_a.label) {
|
|
98
|
+
case 0:
|
|
99
|
+
db = (0, db_1.getDbAsSystem)();
|
|
100
|
+
return [4 /*yield*/, db.delete(user_1.tables.AccessGrant, {})];
|
|
101
|
+
case 1:
|
|
102
|
+
_a.sent();
|
|
103
|
+
return [4 /*yield*/, db.delete(user_1.tables.User, {})];
|
|
104
|
+
case 2:
|
|
105
|
+
_a.sent();
|
|
106
|
+
return [4 /*yield*/, testEnv.createUser({ name: 'Alice Principal', email: 'alice@test.local' })];
|
|
107
|
+
case 3:
|
|
108
|
+
alice = _a.sent();
|
|
109
|
+
return [4 /*yield*/, testEnv.createUser({ name: 'Ada Admin', email: 'admin@test.local', roles: ['admin'] })];
|
|
110
|
+
case 4:
|
|
111
|
+
admin = _a.sent();
|
|
112
|
+
return [4 /*yield*/, testEnv.createUser({ name: 'Sam Stranger', email: 'stranger@test.local' })];
|
|
113
|
+
case 5:
|
|
114
|
+
stranger = _a.sent();
|
|
115
|
+
return [2 /*return*/];
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}); });
|
|
119
|
+
/** A system-conferred grant for `principal` on `resource` (the SharedRecord-bootstrap shape). */
|
|
120
|
+
var conferGrant = function (principal, resource, accessLevel) { return __awaiter(void 0, void 0, void 0, function () {
|
|
121
|
+
return __generator(this, function (_a) {
|
|
122
|
+
switch (_a.label) {
|
|
123
|
+
case 0: return [4 /*yield*/, (0, db_1.getDbAsSystem)().insert(user_1.tables.AccessGrant, {
|
|
124
|
+
principal: new db_1.Reference(user_1.tables.User.name, principal.id),
|
|
125
|
+
resource: new db_1.Reference(user_1.tables.User.name, resource.id),
|
|
126
|
+
resourceTable: user_1.tables.User.name,
|
|
127
|
+
accessLevel: accessLevel,
|
|
128
|
+
})];
|
|
129
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}); };
|
|
133
|
+
it('PREMISE: the stored principal cell is the bare user id — the table name lives only in the declaration', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
134
|
+
var grant, rawRows;
|
|
135
|
+
return __generator(this, function (_a) {
|
|
136
|
+
switch (_a.label) {
|
|
137
|
+
case 0: return [4 /*yield*/, conferGrant(alice, alice, 'owner')];
|
|
138
|
+
case 1:
|
|
139
|
+
grant = _a.sent();
|
|
140
|
+
return [4 /*yield*/, testEnv.spannerDriver.runQuery((function () { return ({
|
|
141
|
+
sql: "SELECT principal, resource, resource_table FROM access_grant WHERE id = '".concat(grant.id, "'"),
|
|
142
|
+
}); }))];
|
|
143
|
+
case 2:
|
|
144
|
+
rawRows = _a.sent();
|
|
145
|
+
expect(rawRows).toHaveLength(1);
|
|
146
|
+
expect(rawRows[0].principal).toBe(alice.id);
|
|
147
|
+
expect(rawRows[0].resource).toBe(alice.id);
|
|
148
|
+
expect(rawRows[0].resource_table).toBe('user');
|
|
149
|
+
// Nothing 'UserTable'-shaped is stored anywhere in the row's reference cells.
|
|
150
|
+
expect(JSON.stringify(rawRows[0])).not.toContain('UserTable');
|
|
151
|
+
return [2 /*return*/];
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}); });
|
|
155
|
+
it('a read-back grant principal carries the user table name and resolves the user record', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
156
|
+
var inserted, grant, principalUser;
|
|
157
|
+
return __generator(this, function (_a) {
|
|
158
|
+
switch (_a.label) {
|
|
159
|
+
case 0: return [4 /*yield*/, conferGrant(alice, alice, 'owner')];
|
|
160
|
+
case 1:
|
|
161
|
+
inserted = _a.sent();
|
|
162
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().get(user_1.tables.AccessGrant, { id: inserted.id })];
|
|
163
|
+
case 2:
|
|
164
|
+
grant = _a.sent();
|
|
165
|
+
expect(grant.principal._id).toBe(alice.id);
|
|
166
|
+
// The read-back reference's table comes from the COLUMN DECLARATION (deserialize) — this is
|
|
167
|
+
// the line under test: 'UserTable' here means the class name leaked into the declaration.
|
|
168
|
+
expect(grant.principal._table).toBe('user');
|
|
169
|
+
// The admin-surface consumer's path: resolve the principal by reference, as the admin.
|
|
170
|
+
testEnv.actAs(admin);
|
|
171
|
+
return [4 /*yield*/, grant.principal.get()];
|
|
172
|
+
case 3:
|
|
173
|
+
principalUser = _a.sent();
|
|
174
|
+
expect(principalUser).toMatchObject({ id: alice.id, name: 'Alice Principal' });
|
|
175
|
+
return [2 /*return*/];
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}); });
|
|
179
|
+
it('NON-REGRESSION: the admin/owner insert gate still keys on stored principal ids', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
180
|
+
var grants;
|
|
181
|
+
return __generator(this, function (_a) {
|
|
182
|
+
switch (_a.label) {
|
|
183
|
+
case 0: return [4 /*yield*/, conferGrant(admin, alice, 'owner')];
|
|
184
|
+
case 1:
|
|
185
|
+
_a.sent();
|
|
186
|
+
// The owner confers read to another user through the caller-context path — the gate finds
|
|
187
|
+
// the caller's own grant by principal-ID equality against the stored rows.
|
|
188
|
+
testEnv.actAs(admin);
|
|
189
|
+
return [4 /*yield*/, (0, db_1.getDb)().insert(user_1.tables.AccessGrant, {
|
|
190
|
+
principal: new db_1.Reference(user_1.tables.User.name, stranger.id),
|
|
191
|
+
resource: new db_1.Reference(user_1.tables.User.name, alice.id),
|
|
192
|
+
resourceTable: user_1.tables.User.name,
|
|
193
|
+
accessLevel: 'read',
|
|
194
|
+
})];
|
|
195
|
+
case 2:
|
|
196
|
+
_a.sent();
|
|
197
|
+
return [4 /*yield*/, (0, db_1.getDbAsSystem)().query(user_1.tables.AccessGrant, { resource: alice.id })];
|
|
198
|
+
case 3:
|
|
199
|
+
grants = _a.sent();
|
|
200
|
+
expect(grants.map(function (grant) { return ({ principal: grant.principal._id, accessLevel: grant.accessLevel }); })).toEqual(expect.arrayContaining([
|
|
201
|
+
{ principal: admin.id, accessLevel: 'owner' },
|
|
202
|
+
{ principal: stranger.id, accessLevel: 'read' },
|
|
203
|
+
]));
|
|
204
|
+
// A caller with NO grant on the resource is still refused.
|
|
205
|
+
testEnv.actAs(stranger);
|
|
206
|
+
return [4 /*yield*/, expect((0, db_1.getDb)().insert(user_1.tables.AccessGrant, {
|
|
207
|
+
principal: new db_1.Reference(user_1.tables.User.name, stranger.id),
|
|
208
|
+
resource: new db_1.Reference(user_1.tables.User.name, alice.id),
|
|
209
|
+
resourceTable: user_1.tables.User.name,
|
|
210
|
+
accessLevel: 'admin',
|
|
211
|
+
})).rejects.toThrow('User does not have admin access to resource')];
|
|
212
|
+
case 4:
|
|
213
|
+
_a.sent();
|
|
214
|
+
return [2 /*return*/];
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
}); });
|
|
218
|
+
});
|
|
219
|
+
//# sourceMappingURL=AccessGrantPrincipalReference.integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AccessGrantPrincipalReference.integration.test.js","sourceRoot":"","sources":["../../test/AccessGrantPrincipalReference.integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -114,18 +114,21 @@ describe('invite token lifetime', function () {
|
|
|
114
114
|
});
|
|
115
115
|
it('stamps tokenExpiresAt from the knob when creating an invite', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
116
116
|
var response, _a, inserted;
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
var _b, _c;
|
|
118
|
+
return __generator(this, function (_d) {
|
|
119
|
+
switch (_d.label) {
|
|
119
120
|
case 0:
|
|
120
121
|
dbGet.mockResolvedValue(undefined); // no existing user, no existing invite
|
|
121
122
|
return [4 /*yield*/, new Signup_1.Signup().sendInvite('Invitee@Test.local')];
|
|
122
123
|
case 1:
|
|
123
|
-
response =
|
|
124
|
+
response = _d.sent();
|
|
124
125
|
expect(response.sent).toBe(true);
|
|
125
126
|
expect(dbInsert).toHaveBeenCalledTimes(1);
|
|
126
127
|
_a = dbInsert.mock.calls[0], inserted = _a[1];
|
|
127
128
|
expect(inserted.email).toBe('invitee@test.local');
|
|
128
|
-
|
|
129
|
+
// The inviter is stamped as a REFERENCE to the user record (the id string rides inside it).
|
|
130
|
+
expect((_b = inserted.invitedBy) === null || _b === void 0 ? void 0 : _b._table).toBe('user');
|
|
131
|
+
expect((_c = inserted.invitedBy) === null || _c === void 0 ? void 0 : _c._id).toBe('inviter-1');
|
|
129
132
|
expect(secondsFromExpectedTtl(inserted.tokenExpiresAt, Signup_1.INVITE_TOKEN_TTL_DAYS)).toBeLessThan(CLOCK_SKEW_TOLERANCE_SECONDS);
|
|
130
133
|
// Pin the value too, so changing the constant is a deliberate act rather than a drive-by.
|
|
131
134
|
expect(secondsFromExpectedTtl(inserted.tokenExpiresAt, EXPECTED_TTL_DAYS)).toBeLessThan(CLOCK_SKEW_TOLERANCE_SECONDS);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignupInvite.test.js","sourceRoot":"","sources":["../../test/SignupInvite.test.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"SignupInvite.test.js","sourceRoot":"","sources":["../../test/SignupInvite.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -194,38 +194,42 @@ describe('signup route — auto-login after signup', function () {
|
|
|
194
194
|
}); });
|
|
195
195
|
it('invited signup resolves the email from the invite, consumes it, and establishes the session', function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
196
196
|
var db, outcome, created, _a;
|
|
197
|
-
|
|
198
|
-
|
|
197
|
+
var _b, _c;
|
|
198
|
+
return __generator(this, function (_d) {
|
|
199
|
+
switch (_d.label) {
|
|
199
200
|
case 0:
|
|
200
201
|
db = (0, db_1.getDbAsSystem)();
|
|
201
202
|
return [4 /*yield*/, db.insert(user_1.tables.Invite, {
|
|
202
203
|
email: 'invited@test.local',
|
|
203
204
|
token: 'invite-token-1',
|
|
204
205
|
tokenExpiresAt: (0, moment_1.default)().add(1, 'day'),
|
|
205
|
-
invitedBy: 'inviter-1',
|
|
206
|
+
invitedBy: new db_1.Reference(user_1.tables.User.name, 'inviter-1'),
|
|
206
207
|
})];
|
|
207
208
|
case 1:
|
|
208
|
-
|
|
209
|
+
_d.sent();
|
|
209
210
|
return [4 /*yield*/, invokeSignup({
|
|
210
211
|
name: 'Invited Signup',
|
|
211
212
|
password: 'pw-invited-1',
|
|
212
213
|
token: 'invite-token-1',
|
|
213
214
|
})];
|
|
214
215
|
case 2:
|
|
215
|
-
outcome =
|
|
216
|
+
outcome = _d.sent();
|
|
216
217
|
expect(outcome.body).toEqual({});
|
|
217
218
|
expect(outcome.loggedInAs).toBe('invited@test.local');
|
|
218
219
|
expect(outcome.sessionEvents).toEqual(['regenerate', 'login', 'save']);
|
|
219
220
|
return [4 /*yield*/, getUserRow('invited@test.local')];
|
|
220
221
|
case 3:
|
|
221
|
-
created =
|
|
222
|
+
created = _d.sent();
|
|
222
223
|
expect(created).toBeDefined();
|
|
223
224
|
expect(created.emailVerified).toBe(true); // the email came from the invite record
|
|
224
|
-
|
|
225
|
+
// The inviter carries over from the invite as a reference to the user record — the stored
|
|
226
|
+
// bytes stay the raw id, so it reads back as a reference to the same id.
|
|
227
|
+
expect((_b = created.invitedBy) === null || _b === void 0 ? void 0 : _b._table).toBe(user_1.tables.User.name);
|
|
228
|
+
expect((_c = created.invitedBy) === null || _c === void 0 ? void 0 : _c._id).toBe('inviter-1');
|
|
225
229
|
_a = expect;
|
|
226
230
|
return [4 /*yield*/, db.get(user_1.tables.Invite, { token: 'invite-token-1' })];
|
|
227
231
|
case 4:
|
|
228
|
-
_a.apply(void 0, [
|
|
232
|
+
_a.apply(void 0, [_d.sent()]).toBeUndefined();
|
|
229
233
|
return [2 /*return*/];
|
|
230
234
|
}
|
|
231
235
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignupRoute.test.js","sourceRoot":"","sources":["../../test/SignupRoute.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAA4B;AAE5B;;;;;;;;;;;;;;;;GAgBG;AAEH,IAAM,SAAS,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;AAE5B,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,cAAM,OAAA,CAAC;IAC1C,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,cAAM,OAAA,CAAC,EAAE,SAAS,WAAA,EAAE,CAAC,EAAf,CAAe,CAAC;IAChE,kCAAkC,EAAE,cAAM,OAAA,CAAC;QACzC,SAAS,EAAE,cAAM,OAAA,CAAC,EAAE,eAAe,EAAE,cAAM,OAAA,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,EAA3C,CAA2C,EAAE,CAAC,EAAxE,CAAwE;KAC1F,CAAC,EAFwC,CAExC;IACF,8CAA8C,EAAE,cAAM,OAAA,CAAC;QACrD,SAAS,EAAE,cAAM,OAAA,CAAC;YAChB,sBAAsB,EAAE,cAAM,OAAA,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,EAA7C,CAA6C;YAC3E,2BAA2B,EAAE,cAAM,OAAA,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,EAA3C,CAA2C;SAC/E,CAAC,EAHe,CAGf;KACH,CAAC,EALoD,CAKpD;CACH,CAAC,EAXyC,CAWzC,CAAC,CAAC;AAEJ,
|
|
1
|
+
{"version":3,"file":"SignupRoute.test.js","sourceRoot":"","sources":["../../test/SignupRoute.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@proteinjs/user-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.1",
|
|
4
4
|
"description": "User server components",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"@proteinjs/reflection": "^1.2.0",
|
|
30
30
|
"@proteinjs/server": "^3.5.1",
|
|
31
31
|
"@proteinjs/server-api": "^3.0.11",
|
|
32
|
-
"@proteinjs/user": "^1.
|
|
32
|
+
"@proteinjs/user": "^1.12.1",
|
|
33
33
|
"argon2": "^0.45.1",
|
|
34
34
|
"crypto-js": "4.0.0",
|
|
35
35
|
"express-session": "1.17.1",
|
|
@@ -58,5 +58,5 @@
|
|
|
58
58
|
},
|
|
59
59
|
"main": "./dist/generated/index.js",
|
|
60
60
|
"types": "./dist/generated/index.d.ts",
|
|
61
|
-
"gitHead": "
|
|
61
|
+
"gitHead": "afc8981f566682ae188b8a204d4a2fe0669bbd11"
|
|
62
62
|
}
|
package/src/services/Signup.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getDbAsSystem } from '@proteinjs/db';
|
|
1
|
+
import { getDbAsSystem, Reference } from '@proteinjs/db';
|
|
2
2
|
import {
|
|
3
3
|
SendInviteResponse,
|
|
4
4
|
tables,
|
|
@@ -184,7 +184,7 @@ export class Signup implements SignupService {
|
|
|
184
184
|
email: caseInsensitiveEmail,
|
|
185
185
|
token,
|
|
186
186
|
tokenExpiresAt,
|
|
187
|
-
invitedBy: userId,
|
|
187
|
+
invitedBy: new Reference(tables.User.name, userId),
|
|
188
188
|
});
|
|
189
189
|
}
|
|
190
190
|
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { getDb, getDbAsSystem, Reference, ReferenceColumn } from '@proteinjs/db';
|
|
2
|
+
import { SourceRepository } from '@proteinjs/reflection';
|
|
3
|
+
import { AccessGrant, tables, User } from '@proteinjs/user';
|
|
4
|
+
import { UserServerTestEnvironment } from './UserServerTestEnvironment';
|
|
5
|
+
|
|
6
|
+
const testEnv = new UserServerTestEnvironment();
|
|
7
|
+
|
|
8
|
+
type SourceRepositoryInternals = { objectCache: { [qualifiedName: string]: unknown[] } };
|
|
9
|
+
const objectCache = () => (SourceRepository.get() as unknown as SourceRepositoryInternals).objectCache;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* AccessGrant.principal is a REFERENCE to the `user` table (the 2026-08 declaration bug: the
|
|
13
|
+
* column named its reference table `UserTable.name` — the class's static JS name, `'UserTable'` —
|
|
14
|
+
* not the table's declared name `'user'`).
|
|
15
|
+
*
|
|
16
|
+
* PREMISE (why the fix is declaration-only): `ReferenceColumn.serialize` stores the bare id —
|
|
17
|
+
* the reference's table name lives ONLY in the column declaration, which `deserialize` stamps
|
|
18
|
+
* onto every read-back `Reference`. The first test asserts that against the live emulator: the
|
|
19
|
+
* raw stored `principal` cell is exactly the principal's user id. Zero data is touched by the
|
|
20
|
+
* fix and the schema sync sees no change (same STRING(36) column either way).
|
|
21
|
+
*
|
|
22
|
+
* SURFACE: `grant.principal.get()` resolves through `tableByName(reference._table)` — with the
|
|
23
|
+
* class name stamped on it, resolution throws `Unable to find table: UserTable`, so the admin
|
|
24
|
+
* grant table could never render principals as linked names (db-ui's ReferenceCellValue rides
|
|
25
|
+
* this same `Reference.get()`; the ui-package suite binds that rendering surface).
|
|
26
|
+
*
|
|
27
|
+
* NON-REGRESSION: the grant machinery itself compares stored PRINCIPAL IDS, never the
|
|
28
|
+
* declaration's table name — the admin/owner insert gate must behave identically before and
|
|
29
|
+
* after the fix (pinned by the caller-context legs).
|
|
30
|
+
*/
|
|
31
|
+
describe('AccessGrant.principal reference — stored bare ids; declaration resolves the user table', () => {
|
|
32
|
+
let alice: User;
|
|
33
|
+
let admin: User;
|
|
34
|
+
let stranger: User;
|
|
35
|
+
|
|
36
|
+
beforeAll(async () => {
|
|
37
|
+
await testEnv.beforeAll();
|
|
38
|
+
// Reference.get() resolves tables by NAME off the source graph (not loaded in tests) —
|
|
39
|
+
// register exactly this package's tables, as the app's composition would.
|
|
40
|
+
objectCache()['@proteinjs/db/Table'] = Object.values(tables);
|
|
41
|
+
}, 120_000);
|
|
42
|
+
|
|
43
|
+
afterAll(async () => {
|
|
44
|
+
delete objectCache()['@proteinjs/db/Table'];
|
|
45
|
+
await testEnv.afterAll();
|
|
46
|
+
}, 60_000);
|
|
47
|
+
|
|
48
|
+
beforeEach(async () => {
|
|
49
|
+
const db = getDbAsSystem();
|
|
50
|
+
await db.delete(tables.AccessGrant, {});
|
|
51
|
+
await db.delete(tables.User, {});
|
|
52
|
+
alice = await testEnv.createUser({ name: 'Alice Principal', email: 'alice@test.local' });
|
|
53
|
+
admin = await testEnv.createUser({ name: 'Ada Admin', email: 'admin@test.local', roles: ['admin'] });
|
|
54
|
+
stranger = await testEnv.createUser({ name: 'Sam Stranger', email: 'stranger@test.local' });
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
/** A system-conferred grant for `principal` on `resource` (the SharedRecord-bootstrap shape). */
|
|
58
|
+
const conferGrant = async (
|
|
59
|
+
principal: User,
|
|
60
|
+
resource: User,
|
|
61
|
+
accessLevel: AccessGrant['accessLevel']
|
|
62
|
+
): Promise<AccessGrant> =>
|
|
63
|
+
await getDbAsSystem().insert(tables.AccessGrant, {
|
|
64
|
+
principal: new Reference<User>(tables.User.name, principal.id),
|
|
65
|
+
resource: new Reference<User>(tables.User.name, resource.id),
|
|
66
|
+
resourceTable: tables.User.name,
|
|
67
|
+
accessLevel,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('PREMISE: the stored principal cell is the bare user id — the table name lives only in the declaration', async () => {
|
|
71
|
+
const grant = await conferGrant(alice, alice, 'owner');
|
|
72
|
+
|
|
73
|
+
const rawRows = await testEnv.spannerDriver.runQuery((() => ({
|
|
74
|
+
sql: `SELECT principal, resource, resource_table FROM access_grant WHERE id = '${grant.id}'`,
|
|
75
|
+
})) as Parameters<typeof testEnv.spannerDriver.runQuery>[0]);
|
|
76
|
+
|
|
77
|
+
expect(rawRows).toHaveLength(1);
|
|
78
|
+
expect(rawRows[0].principal).toBe(alice.id);
|
|
79
|
+
expect(rawRows[0].resource).toBe(alice.id);
|
|
80
|
+
expect(rawRows[0].resource_table).toBe('user');
|
|
81
|
+
// Nothing 'UserTable'-shaped is stored anywhere in the row's reference cells.
|
|
82
|
+
expect(JSON.stringify(rawRows[0])).not.toContain('UserTable');
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('a read-back grant principal carries the user table name and resolves the user record', async () => {
|
|
86
|
+
const inserted = await conferGrant(alice, alice, 'owner');
|
|
87
|
+
|
|
88
|
+
const grant = await getDbAsSystem().get(tables.AccessGrant, { id: inserted.id });
|
|
89
|
+
expect(grant.principal._id).toBe(alice.id);
|
|
90
|
+
// The read-back reference's table comes from the COLUMN DECLARATION (deserialize) — this is
|
|
91
|
+
// the line under test: 'UserTable' here means the class name leaked into the declaration.
|
|
92
|
+
expect(grant.principal._table).toBe('user');
|
|
93
|
+
|
|
94
|
+
// The admin-surface consumer's path: resolve the principal by reference, as the admin.
|
|
95
|
+
testEnv.actAs(admin);
|
|
96
|
+
const principalUser = await grant.principal.get();
|
|
97
|
+
expect(principalUser).toMatchObject({ id: alice.id, name: 'Alice Principal' });
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('NON-REGRESSION: the admin/owner insert gate still keys on stored principal ids', async () => {
|
|
101
|
+
await conferGrant(admin, alice, 'owner');
|
|
102
|
+
|
|
103
|
+
// The owner confers read to another user through the caller-context path — the gate finds
|
|
104
|
+
// the caller's own grant by principal-ID equality against the stored rows.
|
|
105
|
+
testEnv.actAs(admin);
|
|
106
|
+
await getDb().insert(tables.AccessGrant, {
|
|
107
|
+
principal: new Reference<User>(tables.User.name, stranger.id),
|
|
108
|
+
resource: new Reference<User>(tables.User.name, alice.id),
|
|
109
|
+
resourceTable: tables.User.name,
|
|
110
|
+
accessLevel: 'read',
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const grants = await getDbAsSystem().query(tables.AccessGrant, { resource: alice.id });
|
|
114
|
+
expect(grants.map((grant) => ({ principal: grant.principal._id, accessLevel: grant.accessLevel }))).toEqual(
|
|
115
|
+
expect.arrayContaining([
|
|
116
|
+
{ principal: admin.id, accessLevel: 'owner' },
|
|
117
|
+
{ principal: stranger.id, accessLevel: 'read' },
|
|
118
|
+
])
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
// A caller with NO grant on the resource is still refused.
|
|
122
|
+
testEnv.actAs(stranger);
|
|
123
|
+
await expect(
|
|
124
|
+
getDb().insert(tables.AccessGrant, {
|
|
125
|
+
principal: new Reference<User>(tables.User.name, stranger.id),
|
|
126
|
+
resource: new Reference<User>(tables.User.name, alice.id),
|
|
127
|
+
resourceTable: tables.User.name,
|
|
128
|
+
accessLevel: 'admin',
|
|
129
|
+
})
|
|
130
|
+
).rejects.toThrow('User does not have admin access to resource');
|
|
131
|
+
});
|
|
132
|
+
});
|
|
@@ -89,7 +89,9 @@ describe('invite token lifetime', () => {
|
|
|
89
89
|
expect(dbInsert).toHaveBeenCalledTimes(1);
|
|
90
90
|
const [, inserted] = dbInsert.mock.calls[0];
|
|
91
91
|
expect(inserted.email).toBe('invitee@test.local');
|
|
92
|
-
|
|
92
|
+
// The inviter is stamped as a REFERENCE to the user record (the id string rides inside it).
|
|
93
|
+
expect(inserted.invitedBy?._table).toBe('user');
|
|
94
|
+
expect(inserted.invitedBy?._id).toBe('inviter-1');
|
|
93
95
|
expect(secondsFromExpectedTtl(inserted.tokenExpiresAt, INVITE_TOKEN_TTL_DAYS)).toBeLessThan(
|
|
94
96
|
CLOCK_SKEW_TOLERANCE_SECONDS
|
|
95
97
|
);
|
package/test/SignupRoute.test.ts
CHANGED
|
@@ -33,7 +33,7 @@ jest.mock('@proteinjs/email-server', () => ({
|
|
|
33
33
|
}),
|
|
34
34
|
}));
|
|
35
35
|
|
|
36
|
-
import { getDbAsSystem } from '@proteinjs/db';
|
|
36
|
+
import { getDbAsSystem, Reference } from '@proteinjs/db';
|
|
37
37
|
import { SourceRepository } from '@proteinjs/reflection';
|
|
38
38
|
import { tables } from '@proteinjs/user';
|
|
39
39
|
import { signup } from '../src/routes/signup';
|
|
@@ -135,7 +135,7 @@ describe('signup route — auto-login after signup', () => {
|
|
|
135
135
|
email: 'invited@test.local',
|
|
136
136
|
token: 'invite-token-1',
|
|
137
137
|
tokenExpiresAt: moment().add(1, 'day'),
|
|
138
|
-
invitedBy: 'inviter-1',
|
|
138
|
+
invitedBy: new Reference(tables.User.name, 'inviter-1'),
|
|
139
139
|
});
|
|
140
140
|
|
|
141
141
|
const outcome = await invokeSignup({
|
|
@@ -151,7 +151,10 @@ describe('signup route — auto-login after signup', () => {
|
|
|
151
151
|
const created = await getUserRow('invited@test.local');
|
|
152
152
|
expect(created).toBeDefined();
|
|
153
153
|
expect(created!.emailVerified).toBe(true); // the email came from the invite record
|
|
154
|
-
|
|
154
|
+
// The inviter carries over from the invite as a reference to the user record — the stored
|
|
155
|
+
// bytes stay the raw id, so it reads back as a reference to the same id.
|
|
156
|
+
expect(created!.invitedBy?._table).toBe(tables.User.name);
|
|
157
|
+
expect(created!.invitedBy?._id).toBe('inviter-1');
|
|
155
158
|
expect(await db.get(tables.Invite, { token: 'invite-token-1' })).toBeUndefined();
|
|
156
159
|
});
|
|
157
160
|
|