37 lines
2.2 KiB
JavaScript
37 lines
2.2 KiB
JavaScript
// FED R6 (#1800, federation design 3.1 D3 and D5): who besides the owner may sign in to this
|
|
// Console. `load` is R1's loadAccess over this instance's access.json and context, called on every
|
|
// use and never cached, so a revoke, a removed subject or an expired grant counts on the next
|
|
// request. A user is live while one grant in the Console's business covers at `viewer`, the same
|
|
// test as the broker's #userGrants. The broker still decides every verb, project, instance and
|
|
// thread (D4). Any failure to load, or to name the business, finds nobody (fail closed).
|
|
import { covers } from '../../business/src/vocabulary.mjs';
|
|
|
|
export function consoleAccess({ load, business }) {
|
|
if (typeof load !== 'function' || typeof business !== 'function') throw new TypeError('consoleAccess needs load and business functions');
|
|
const live = (doc, id, b) => doc.grants.some(g => g.user === id && g.business === b &&
|
|
covers(g, { business: b, project: g.projects[0], instance: g.instances[0] }, new Date(), { level: 'viewer' }));
|
|
const lookup = (provider, sub) => {
|
|
try {
|
|
const doc = load(), b = business();
|
|
const user = doc.users.find(u => u.subjects.some(s => s.provider === provider && s.sub === sub));
|
|
return user && live(doc, user.id, b) ? user.id : null;
|
|
} catch { return null; }
|
|
};
|
|
return Object.freeze({
|
|
// UI hints only: no grants belonging to another user, receipts or subjects escape.
|
|
chatGrants: session => {
|
|
try {
|
|
if (lookup(session.provider, session.sub) !== session.user) return [];
|
|
const doc = load(), b = business();
|
|
return doc.grants.filter(g => g.user === session.user && g.business === b &&
|
|
covers(g, { business: b, project: g.projects[0], instance: g.instances[0] }, new Date(), { level: 'collaborator' }))
|
|
.map(g => ({ projects: [...g.projects], instances: [...g.instances] }));
|
|
} catch { return []; }
|
|
},
|
|
// The user id this (provider, sub) signs in as, or null.
|
|
find: ({ provider, sub }) => lookup(provider, sub),
|
|
// Is this session's user still the holder of its own subject, with a live grant?
|
|
check: session => typeof session?.user === 'string' && lookup(session.provider, session.sub) === session.user,
|
|
});
|
|
}
|