Spreadsheet-UX op een echte relationele engine
Deze repository wordt als momentopname gepubliceerd: een clone bevat de volledige inhoud, maar geen commitgeschiedenis.
/**
* Whose licence this install runs under.
*
* `WELLFORMED_LICENSE` holds a licence line: a short statement, signed by the
* copyright holder, naming the party the licence was granted to. The software
* reads it, checks the signature against the keys it was built with, and says
* on start whose it is.
*
* What that setting is *not* is a lock. Wellformed starts either way and no
* data is ever out of reach because of it. What a valid licence changes is
* that the hosted plans stop applying — which is the honest consequence, since
* a plan is a thing you buy from Bram and a licensed install has already
* settled that on paper.
*
* The line asserts something attributable, and that is the whole of its force:
* an installation carrying it is claiming, in a form nobody else can forge, to
* be running under a named party's licence. Copying an install copies that
* name along with it.
*/
import { LICENCE_PRODUCT, LICENCE_PUBLIC_KEYS } from './key.js';
import { describeLicence, verifyLicence, LicenceError, type Licence, type LicenceFault } from './verify.js';
export type LicenceState =
/** Signed, checked, and for this software. */
| { status: 'licensed'; licence: Licence; description: string }
/** Nothing set. The ordinary state of the hosted service and of a trial. */
| { status: 'none' }
/**
* The setting still holds one of the mode words this used to take.
*
* Worth its own state rather than a parse failure: an install upgrading from
* a version where `selfhosted` meant something deserves to be told what
* changed, not told its licence is malformed.
*/
| { status: 'legacy'; word: string }
/** Something is there, and it is not a licence this software accepts. */
| { status: 'rejected'; fault: LicenceFault; message: string };
const LEGACY_WORDS = new Set(['hosted', 'selfhosted', 'self-hosted']);
export function readLicence(value: string | undefined = process.env.WELLFORMED_LICENSE): LicenceState {
const raw = value?.trim() ?? '';
if (raw === '') return { status: 'none' };
if (LEGACY_WORDS.has(raw.toLowerCase())) return { status: 'legacy', word: raw };
try {
const licence = verifyLicence(raw, LICENCE_PUBLIC_KEYS, { product: LICENCE_PRODUCT });
return { status: 'licensed', licence, description: describeLicence(licence) };
} catch (error) {
if (error instanceof LicenceError) return { status: 'rejected', fault: error.fault, message: error.message };
throw error;
}
}
/** The name to show an operator, or null where there is no licence to name. */
export function licensedTo(state: LicenceState): string | null {
return state.status === 'licensed' ? state.description : null;
}
/**
* What to print on start.
*
* A licensed install gets one line, because that is a fact and not a warning.
* Everything else gets said plainly enough that an operator who set the value
* and got it wrong finds out now rather than from a support thread later.
*/
export function licenceNotice(state: LicenceState): string[] {
switch (state.status) {
case 'licensed':
return [`[wellformed] licensed to ${state.description}`];
case 'none':
return ['[wellformed] no licence set — the hosted plans apply on this install'];
case 'legacy':
return [
`[wellformed] WELLFORMED_LICENSE=${state.word} is no longer a setting this understands.`,
' It used to be a mode word. It now holds the licence itself: one signed line,',
' naming the party the licence was granted to. Until one is set, the hosted',
' plans apply. Ask the copyright holder for the licence line.',
];
case 'rejected':
return [
`[wellformed] the licence in WELLFORMED_LICENSE was not accepted: ${state.message}`,
' The hosted plans apply until it is. If the line was pasted, check that all of',
' it is on one line, unbroken and unquoted.',
];
}
}