Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/missionmatch / frontend/src/lib/homeTool.ts |
| Date | Not specified in source |
| Repository | Janady13/missionmatch |
| Revision | 720d47fae476b0d38477ae4401697d372b1ea2bc |
| Branch | feature/opportunity-to-outcome |
| Path or archive member | frontend/src/lib/homeTool.ts |
| Original SHA-256 | b71e4132247422e17161f7cb55dac1cf87339f834bba52492bc44b7d9ced33cd |
| Git blob SHA | 317642deacc11717a29f0679df346f2bf1ff0fe4 |
| Reading-copy SHA-256 | b71e4132247422e17161f7cb55dac1cf87339f834bba52492bc44b7d9ced33cd |
Every recorded occurrence
These 2 records contain identical original source bytes. Their paths and revisions remain part of the archive.
| Original record | Branch or archive | Revision / identifier | Original location |
|---|---|---|---|
| Janady13/missionmatch / frontend/src/lib/homeTool.ts | feature/opportunity-to-outcome | 720d47fae476b0d38477ae4401697d372b1ea2bc | Open original |
| Janady13/missionmatch / frontend/src/lib/homeTool.ts | feature/aioe-upgrade | 2178e7298d0e5d9af83afa12402fd587f0ba6ed8 | Open original |
Recovered source transcript
Download complete source text ↓58 lines · 2.9 KB
import type { SessionPrincipal } from './auth'
import { hasTool } from './can'
// Where a user lands after signing in, and which tool routes they may reach.
//
// The landing route used to be an unconditional redirect to /command. That is missionMATCH, and the
// navigation hides missionMATCH from anyone without the grant, so a recruitMATCH only user signed in, was
// sent to a tool they do not have, and got a permanent error panel with a Try again button that could
// never succeed, beside a sidebar that did not contain the screen they were looking at. The API was right
// to refuse; the interface simply insisted on going there.
// TOOL_HOME maps an entitlement to the path that tool opens on, in the order the navigation presents them.
// The first tool a user actually holds is their home.
export const TOOL_HOME: { tool: string; path: string }[] = [
{ tool: 'missionmatch', path: '/command' },
{ tool: 'screenmatch', path: '/screen' },
{ tool: 'slatematch', path: '/slate' },
{ tool: 'recruitmatch', path: '/recruit' },
]
// homePath returns the landing route for this principal.
//
// Falls back to /settings rather than to a tool when the user holds nothing. An account with no
// entitlement can still legitimately sign in (it may be mid provisioning, or deliberately parked), and
// settings is the one authenticated screen that needs no product. Sending them to a tool instead would
// reproduce the exact dead end this function exists to remove.
export function homePath(principal: SessionPrincipal | null): string {
for (const t of TOOL_HOME) {
if (hasTool(principal, t.tool)) return t.path
}
return '/settings'
}
// TOOL_ROUTE_PREFIXES maps each route prefix to the entitlement it requires, so a route the user is not
// entitled to redirects home instead of rendering a screen whose every request will be refused.
//
// This mirrors the server side gate in internal/platform/security/tools.go rather than replacing it: the
// API refuses independently, and this only stops the interface from offering a journey that ends in an
// error. Cross tool links exist (a candidate card links into screenMATCH to evaluate), so without this a
// user can be walked into an unentitled tool by a button rather than by typing a URL.
export const TOOL_ROUTE_PREFIXES: { prefix: string; tool: string }[] = [
{ prefix: '/command', tool: 'missionmatch' },
{ prefix: '/compliance', tool: 'missionmatch' },
{ prefix: '/screen', tool: 'screenmatch' },
{ prefix: '/requirements', tool: 'screenmatch' },
{ prefix: '/slate', tool: 'slatematch' },
{ prefix: '/recruit', tool: 'recruitmatch' },
]
// toolForPath returns the entitlement a path requires, or null when it belongs to no tool (settings,
// admin, the not found screen).
export function toolForPath(path: string): string | null {
for (const r of TOOL_ROUTE_PREFIXES) {
if (path === r.prefix || path.startsWith(r.prefix + '/')) return r.tool
}
return null
}