76 lines
3.4 KiB
TypeScript
76 lines
3.4 KiB
TypeScript
import type { ConsoleRole } from './roles';
|
|
|
|
/**
|
|
* Who may sign in to the merchant console.
|
|
*
|
|
* ── Why this is a constant ──────────────────────────────────────────────────
|
|
*
|
|
* There was a `VITE_WORKSPACE` build flag here while one codebase served both
|
|
* consoles and had to be told which it was. That is over: Nearle's own staff
|
|
* have their own application, `nearle-platform`, and this repository is the
|
|
* merchant console and nothing else. A flag would only be a way to deploy this
|
|
* application as something it is not.
|
|
*
|
|
* ── The separation is a refusal, not a redirect ─────────────────────────────
|
|
*
|
|
* A Nearle staff account is turned away here with a sentence naming where it
|
|
* belongs. It is not bounced to the other site carrying a half-made session.
|
|
*
|
|
* The role is not known until the password has been checked — `applogin`
|
|
* returns it — so the refusal can only happen after credentials are verified.
|
|
* `login` applies it BEFORE the session is written and `restore` applies it to
|
|
* what is already stored. That order is the point: a session persisted first
|
|
* and refused afterwards leaves somebody signed in by every measure the shell
|
|
* uses, with a nav built from a role this application serves no routes for.
|
|
*/
|
|
export const WORKSPACE = 'merchant' as const;
|
|
|
|
const ALLOWED: ReadonlySet<ConsoleRole> = new Set<ConsoleRole>(['store-admin', 'store-manager']);
|
|
|
|
export function isAllowedHere(role: ConsoleRole): boolean {
|
|
return ALLOWED.has(role);
|
|
}
|
|
|
|
/**
|
|
* The platform console's address, for the sentence shown to a staff member who
|
|
* signs in at the wrong site.
|
|
*
|
|
* A build variable rather than a constant, because the two are separate
|
|
* deployments and either can move. The fallback is the production hostname,
|
|
* which is right far more often than saying nothing would be.
|
|
*/
|
|
const PLATFORM_HOST =
|
|
(import.meta.env?.['VITE_PLATFORM_HOST'] ?? '').trim() || 'platform.nearledaily.com';
|
|
|
|
/**
|
|
* Names the host rather than linking to it. A live link from one sign-in screen
|
|
* to another reads as a redirect that failed, and this is not a failure — it is
|
|
* the right answer to the wrong door.
|
|
*
|
|
* Both consoles say this the same way — "That is a X account. Sign in at Y." —
|
|
* because a person only ever sees one of them and the pair should not read as
|
|
* two different products. The earlier versions did: one opened "This is the
|
|
* Nearle platform console…", the other closed with "…not here."
|
|
*
|
|
* It addresses what they typed rather than describing a category of account.
|
|
* "Store admin accounts sign in at…" is true of accounts in general; "That is a
|
|
* Store admin account" is about the one in the box in front of them.
|
|
*/
|
|
export function wrongConsoleMessage(role: ConsoleRole): string {
|
|
return `That is a ${roleWord(role)} account. Sign in at ${PLATFORM_HOST}.`;
|
|
}
|
|
|
|
function roleWord(role: ConsoleRole): string {
|
|
switch (role) {
|
|
case 'nearle-admin':
|
|
return 'Nearle staff';
|
|
// Unreachable: both merchant roles are allowed here, so neither reaches the
|
|
// refusal. Present because the switch is exhaustive over the union and a
|
|
// missing arm would be a type error the day a role is added.
|
|
case 'store-admin':
|
|
return 'Store admin';
|
|
case 'store-manager':
|
|
return 'Store user';
|
|
}
|
|
}
|