@bongos/core 1.20.21 → 1.20.23
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/.bongos-core.json +78 -48
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +4 -2
- package/clients/bongos-client/index.cjs +4 -2
- package/clients/bongos-client/index.d.ts +8 -4
- package/clients/bongos-client/index.mjs +4 -2
- package/docs/adr/0335-an-invite-is-a-pre-approved-row-on-the-projects-own-instance.md +1 -0
- package/docs/adr/0353-a-hub-invite-is-a-notice-of-the-projects-own-invite.md +70 -0
- package/docs/adr/README.md +1 -0
- package/docs/api/openapi.json +137 -72
- package/docs/api-reference.md +6 -5
- package/docs/architecture.md +14 -0
- package/docs/copy-inventory.md +196 -196
- package/docs/copy-registry.json +250 -250
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-inventory.json +2 -1
- package/docs/page-readings.json +310 -306
- package/migrations/core_265_module_assessments.sql +97 -0
- package/modules/hall-ui/public/watch.js +23 -0
- package/modules/onboarding/routes/access-requests.js +36 -6
- package/modules/platform-identity/invite-notices.js +61 -0
- package/modules/platform-identity/module.json +1 -1
- package/modules/platform-identity/platform-identity.js +12 -18
- package/modules/platform-identity/routes/my-projects.js +6 -15
- package/modules/platform-identity/routes/projects.js +22 -15
- package/modules/platform-identity/routes/sso-invites.js +82 -0
- package/modules/platform-identity/tests/platform-identity.mjs +14 -11
- package/modules/public-landing/public/assets/cosmos.css +5 -0
- package/modules/public-landing/public/projects.html +35 -29
- package/modules/public-landing/public/projects.states.json +1 -0
- package/modules/ui-design/kit/serve.js +9 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/src/bongos/auth-admission.js +40 -0
- package/src/bongos/auth.js +2 -1
- package/src/module-api.js +8 -1
- package/tests/access_requests_invite.mjs +39 -1
- package/tests/application_lifecycle.mjs +41 -1
- package/tests/catalog_only_client.mjs +5 -3
- package/tests/hub_invite_notices.mjs +261 -0
- package/tests/module_api.mjs +1 -0
- package/tests/module_assessments_migration.mjs +96 -0
- package/tests/my_projects_surface.mjs +11 -1
- package/tests/project_invite_ownership.mjs +12 -7
- package/tests/project_invite_ui.mjs +42 -45
- package/tests/watch_applications_queue.mjs +33 -2
|
@@ -94,6 +94,7 @@ async function boot(opts = {}) {
|
|
|
94
94
|
rank = 'archon',
|
|
95
95
|
queueStatus = null, // non-200 for the queue read (403 seals it)
|
|
96
96
|
patchResult = null, // a scripted answer for PATCH /access-requests/:id
|
|
97
|
+
search = '', // the page's query string (?invite=<login>, task 1002818)
|
|
97
98
|
} = opts;
|
|
98
99
|
|
|
99
100
|
const requests = [];
|
|
@@ -136,7 +137,7 @@ async function boot(opts = {}) {
|
|
|
136
137
|
// the ones shipped rather than ones this test invented.
|
|
137
138
|
parseInto(documentObj.body, PAGE);
|
|
138
139
|
|
|
139
|
-
const locationObj = { hostname: 'builders.example.test', pathname: '/builders/watch', search
|
|
140
|
+
const locationObj = { hostname: 'builders.example.test', pathname: '/builders/watch', search, hash: '', assign() {} };
|
|
140
141
|
|
|
141
142
|
const kit = {
|
|
142
143
|
makeTabs: () => ({}),
|
|
@@ -187,7 +188,7 @@ async function boot(opts = {}) {
|
|
|
187
188
|
console: { log() {}, warn() {}, error() {} },
|
|
188
189
|
setTimeout, clearTimeout, Promise, Date, Math, JSON, Error, isNaN,
|
|
189
190
|
Number, String, Object, Array, Boolean, Set, Map, RegExp,
|
|
190
|
-
encodeURIComponent, decodeURIComponent, parseInt, parseFloat,
|
|
191
|
+
encodeURIComponent, decodeURIComponent, parseInt, parseFloat, URLSearchParams,
|
|
191
192
|
};
|
|
192
193
|
sandbox.globalThis = sandbox;
|
|
193
194
|
vm.createContext(sandbox);
|
|
@@ -491,4 +492,34 @@ await test('the profile changes what the row SAYS, never what it offers (ADR 001
|
|
|
491
492
|
'a rich record is not a reason to admit and an empty one is not a reason to refuse — the decisions must be identical');
|
|
492
493
|
});
|
|
493
494
|
|
|
495
|
+
// ── ?invite=<login>: the platform hub hands an owner here (task 1002818, ADR 0353) ──
|
|
496
|
+
// The hub's invite widget cannot admit anyone, so it links an owner to THIS box with the
|
|
497
|
+
// name filled in. Filling is all a link may do: the send stays the owner's own click.
|
|
498
|
+
|
|
499
|
+
await test('?invite= fills the invite box — and sends nothing on its own', async () => {
|
|
500
|
+
const h = await boot({ search: '?invite=octo-builder' });
|
|
501
|
+
const box = h.documentObj.getElementById('gate-invite-login');
|
|
502
|
+
assert.ok(box, 'the invite box rendered');
|
|
503
|
+
assert.equal(box.value, 'octo-builder');
|
|
504
|
+
assert.equal(h.requests.filter((r) => r.method === 'POST').length, 0,
|
|
505
|
+
'a link anyone can craft must never be the act that admits');
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
await test('?invite= is spent on first use — a re-render does not put the name back', async () => {
|
|
509
|
+
const h = await boot({ search: '?invite=octo-builder' });
|
|
510
|
+
const box = h.documentObj.getElementById('gate-invite-login');
|
|
511
|
+
box.value = '';
|
|
512
|
+
await h.switchView('invited'); // the gate re-renders, invite box and all
|
|
513
|
+
assert.equal(h.documentObj.getElementById('gate-invite-login').value, '');
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
await test('?invite= that is not a GitHub username fills nothing', async () => {
|
|
517
|
+
for (const bad of ['?invite=%3Cscript%3E', '?invite=a%20b', '?invite=-lead', '?invite=' + 'x'.repeat(40)]) {
|
|
518
|
+
const h = await boot({ search: bad });
|
|
519
|
+
assert.equal(h.documentObj.getElementById('gate-invite-login').value || '', '', bad);
|
|
520
|
+
}
|
|
521
|
+
const at = await boot({ search: '?invite=%40octo' });
|
|
522
|
+
assert.equal(at.documentObj.getElementById('gate-invite-login').value, 'octo', 'a pasted @ is dropped, as the form itself does');
|
|
523
|
+
});
|
|
524
|
+
|
|
494
525
|
summary();
|