docs(api): document the current authentication flow, comment non-obvious auth code

Add a new diagram covering the authentication mechanism: a
session-based /SASLogon/login + /SASLogon/authorize handshake that
mints a short-lived auth code, exchanged at /SASjsApi/auth/token for a
revocable JWT pair, with optional LDAP-backed credential verification.

Add WHY comments (not present before) at the handful of spots in the
auth code whose behaviour isn't obvious from reading them in isolation:
why /auth/token can return an existing token pair instead of rotating
it, why the auth-code exchange never checks a client's clientSecret,
how verifyTokenInDB turns self-verifying JWTs into revocable ones, why
two /SASjsApi/user routes stay reachable in desktop mode, why the
static authorized-route list exists on top of plain authentication,
and why /SASjsApi/client's real protection lives at its router mount
point in routes/api/index.ts rather than in client.ts itself.
This commit is contained in:
YuryShkoda
2026-07-15 16:34:33 +03:00
parent 9c3a1086b6
commit 398dfb515c
7 changed files with 226 additions and 1 deletions
+3
View File
@@ -113,6 +113,9 @@ const authenticateToken = async (
throw 'Unauthorized'
} catch (error) {
// A missing/invalid/expired token doesn't necessarily mean 401 - if an
// admin has granted the built-in Public group access to this exact
// path, an unauthenticated caller still gets through as publicUser.
if (await isPublicRoute(req)) {
req.user = publicUser
return next()
+5
View File
@@ -5,6 +5,11 @@ import { ModeType } from '../utils'
const regexUser = /^\/SASjsApi\/user\/[0-9]*$/ // /SASjsApi/user/1
// Desktop mode has no login/logout (see authenticateAccessToken's desktop
// bypass) and every request runs as the single fixed desktopUser, but the
// desktop UI still needs to read/update that user's own profile (e.g.
// autoExec) - so these two routes stay reachable while every other
// /SASLogon/* and user-management route is blocked below.
const allowedInDesktopMode: { [key: string]: RegExp[] } = {
GET: [regexUser],
PATCH: [regexUser]