Skip to content

TypeScript API / @laikacms/server/oauth2 / UNSAFE_REASONS

Variable: UNSAFE_REASONS ​

ts
const UNSAFE_REASONS: object;

Registry of every condition under which this package refuses to run. Codes are permanent: never renamed, never reused — operators pin them in ignoreUnsafeReasons and crash logs reference them for years.

Type Declaration ​

LCMS_OAUTH2_CSPRNG_DEGENERATE ​

ts
readonly LCMS_OAUTH2_CSPRNG_DEGENERATE: object;

LCMS_OAUTH2_CSPRNG_DEGENERATE.detect ​

ts
readonly detect: (probe) => boolean;
Parameters ​
ParameterType
probeRuntimeProbe
Returns ​

boolean

LCMS_OAUTH2_CSPRNG_DEGENERATE.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_CSPRNG_DEGENERATE.remedy ​

ts
readonly remedy: "Replace the crypto shim or unseeded embedded engine (QuickJS, Hermes, React Native polyfills) with a real platform CSPRNG." = 'Replace the crypto shim or unseeded embedded engine (QuickJS, Hermes, React Native polyfills) with a real platform CSPRNG.';

LCMS_OAUTH2_CSPRNG_DEGENERATE.risk ​

ts
readonly risk: "Two independent 32-byte samples were byte-identical or all-zero — a sound CSPRNG does that with probability ~2^-256, so this RNG is shimmed or unseeded and every token minted from it is predictable." = 'Two independent 32-byte samples were byte-identical or all-zero — a sound CSPRNG does that with probability ~2^-256, so this RNG is shimmed or unseeded and every token minted from it is predictable.';

LCMS_OAUTH2_CSPRNG_DEGENERATE.title ​

ts
readonly title: "The random number generator produced degenerate output" = 'The random number generator produced degenerate output';

LCMS_OAUTH2_CSPRNG_DEGENERATE.when ​

ts
readonly when: "construct" = 'construct';

LCMS_OAUTH2_CSPRNG_MISSING ​

ts
readonly LCMS_OAUTH2_CSPRNG_MISSING: object;

LCMS_OAUTH2_CSPRNG_MISSING.detect ​

ts
readonly detect: (probe) => boolean;
Parameters ​
ParameterType
probeRuntimeProbe
Returns ​

boolean

LCMS_OAUTH2_CSPRNG_MISSING.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_CSPRNG_MISSING.remedy ​

ts
readonly remedy: "Run on a runtime that exposes the Web Crypto API (Node >= 22, Deno, Bun, Cloudflare Workers, or a modern browser). This package will never add a Math.random() fallback." = 'Run on a runtime that exposes the Web Crypto API (Node >= 22, Deno, Bun, Cloudflare Workers, or a modern browser). This package will never add a Math.random() fallback.';

LCMS_OAUTH2_CSPRNG_MISSING.risk ​

ts
readonly risk: "Every authorization code, access token, refresh token, session id and PKCE verifier derives from crypto.getRandomValues; without it they would have to come from a predictable source and any session becomes forgeable." = 'Every authorization code, access token, refresh token, session id and PKCE verifier derives from crypto.getRandomValues; without it they would have to come from a predictable source and any session becomes forgeable.';

LCMS_OAUTH2_CSPRNG_MISSING.title ​

ts
readonly title: "No cryptographically secure random number generator (crypto.getRandomValues)" = 'No cryptographically secure random number generator (crypto.getRandomValues)';

LCMS_OAUTH2_CSPRNG_MISSING.when ​

ts
readonly when: "construct" = 'construct';

LCMS_OAUTH2_HMAC_UNAVAILABLE ​

ts
readonly LCMS_OAUTH2_HMAC_UNAVAILABLE: object;

LCMS_OAUTH2_HMAC_UNAVAILABLE.detect ​

ts
readonly detect: (probe) => Promise<boolean>;
Parameters ​
ParameterType
probeRuntimeProbe
Returns ​

Promise<boolean>

LCMS_OAUTH2_HMAC_UNAVAILABLE.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_HMAC_UNAVAILABLE.remedy ​

ts
readonly remedy: "Use a runtime whose crypto.subtle supports HMAC key generation and signing with SHA-256." = 'Use a runtime whose crypto.subtle supports HMAC key generation and signing with SHA-256.';

LCMS_OAUTH2_HMAC_UNAVAILABLE.risk ​

ts
readonly risk: "Every constant-time comparison in this package is built on HMAC-SHA-256; without it secret comparisons become timing oracles that leak tokens byte by byte." = 'Every constant-time comparison in this package is built on HMAC-SHA-256; without it secret comparisons become timing oracles that leak tokens byte by byte.';

LCMS_OAUTH2_HMAC_UNAVAILABLE.title ​

ts
readonly title: "SubtleCrypto cannot generate or sign with HMAC-SHA-256" = 'SubtleCrypto cannot generate or sign with HMAC-SHA-256';

LCMS_OAUTH2_HMAC_UNAVAILABLE.when ​

ts
readonly when: "first-request" = 'first-request';

LCMS_OAUTH2_IGNORE_LIST_UNKNOWN_CODE ​

ts
readonly LCMS_OAUTH2_IGNORE_LIST_UNKNOWN_CODE: object;

LCMS_OAUTH2_IGNORE_LIST_UNKNOWN_CODE.detect ​

ts
readonly detect: (_probe, input) => boolean;
Parameters ​
ParameterType
_probeRuntimeProbe
inputGateInput
Returns ​

boolean

LCMS_OAUTH2_IGNORE_LIST_UNKNOWN_CODE.ignorable ​

ts
readonly ignorable: false = false;

LCMS_OAUTH2_IGNORE_LIST_UNKNOWN_CODE.remedy ​

ts
readonly remedy: "Remove or correct the unknown entry. Valid codes are the keys of UNSAFE_REASONS exported by this module." = 'Remove or correct the unknown entry. Valid codes are the keys of UNSAFE_REASONS exported by this module.';

LCMS_OAUTH2_IGNORE_LIST_UNKNOWN_CODE.risk ​

ts
readonly risk: "A misspelled entry suppresses nothing while convincing you it did; an ignore list you cannot trust is worse than none." = 'A misspelled entry suppresses nothing while convincing you it did; an ignore list you cannot trust is worse than none.';

LCMS_OAUTH2_IGNORE_LIST_UNKNOWN_CODE.title ​

ts
readonly title: "ignoreUnsafeReasons contains an entry that matches no known code" = 'ignoreUnsafeReasons contains an entry that matches no known code';

LCMS_OAUTH2_IGNORE_LIST_UNKNOWN_CODE.when ​

ts
readonly when: "construct" = 'construct';

LCMS_OAUTH2_INSECURE_CONTEXT ​

ts
readonly LCMS_OAUTH2_INSECURE_CONTEXT: object;

LCMS_OAUTH2_INSECURE_CONTEXT.detect ​

ts
readonly detect: (probe) => boolean;
Parameters ​
ParameterType
probeRuntimeProbe
Returns ​

boolean

LCMS_OAUTH2_INSECURE_CONTEXT.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_INSECURE_CONTEXT.remedy ​

ts
readonly remedy: "Serve the application over HTTPS (or localhost during development) so the user agent grants a secure context." = 'Serve the application over HTTPS (or localhost during development) so the user agent grants a secure context.';

LCMS_OAUTH2_INSECURE_CONTEXT.risk ​

ts
readonly risk: "Without a secure context WebAuthn refuses to operate and bearer tokens travel over the network in cleartext, readable and replayable by any on-path attacker." = 'Without a secure context WebAuthn refuses to operate and bearer tokens travel over the network in cleartext, readable and replayable by any on-path attacker.';

LCMS_OAUTH2_INSECURE_CONTEXT.title ​

ts
readonly title: "Running in an insecure browser context (isSecureContext === false)" = 'Running in an insecure browser context (isSecureContext === false)';

LCMS_OAUTH2_INSECURE_CONTEXT.when ​

ts
readonly when: "construct" = 'construct';

LCMS_OAUTH2_NODE_UNSUPPORTED ​

ts
readonly LCMS_OAUTH2_NODE_UNSUPPORTED: object;

LCMS_OAUTH2_NODE_UNSUPPORTED.detect ​

ts
readonly detect: (probe) => boolean;
Parameters ​
ParameterType
probeRuntimeProbe
Returns ​

boolean

LCMS_OAUTH2_NODE_UNSUPPORTED.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_NODE_UNSUPPORTED.remedy ​

ts
readonly remedy: "Upgrade to a Node.js release still receiving security updates (Node 22 or newer). This code is about patch support alone: it says nothing about the runtime's capabilities, which are probed separately." = "Upgrade to a Node.js release still receiving security updates (Node 22 or newer). This code is about patch support alone: it says nothing about the runtime's capabilities, which are probed separately.";

LCMS_OAUTH2_NODE_UNSUPPORTED.risk ​

ts
readonly risk: "An end-of-life Node release receives no upstream security fixes, so a published vulnerability in its TLS, HTTP or crypto layer stays exploitable underneath this package for as long as the runtime is deployed — and nothing this package does can compensate for a hole below it." = 'An end-of-life Node release receives no upstream security fixes, so a published vulnerability in its TLS, HTTP or crypto layer stays exploitable underneath this package for as long as the runtime is deployed — and nothing this package does can compensate for a hole below it.';

LCMS_OAUTH2_NODE_UNSUPPORTED.title ​

ts
readonly title: "Node.js has reached end-of-life (supported floor >= 22)" = 'Node.js has reached end-of-life (supported floor >= 22)';

LCMS_OAUTH2_NODE_UNSUPPORTED.when ​

ts
readonly when: "construct" = 'construct';

LCMS_OAUTH2_PASSKEY_ES256_UNAVAILABLE ​

ts
readonly LCMS_OAUTH2_PASSKEY_ES256_UNAVAILABLE: object;

LCMS_OAUTH2_PASSKEY_ES256_UNAVAILABLE.detect ​

ts
readonly detect: (probe, input) => Promise<boolean>;
Parameters ​
ParameterType
probeRuntimeProbe
inputGateInput
Returns ​

Promise<boolean>

LCMS_OAUTH2_PASSKEY_ES256_UNAVAILABLE.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_PASSKEY_ES256_UNAVAILABLE.remedy ​

ts
readonly remedy: "Disable passkeys for this deployment, or move to a runtime whose crypto.subtle supports ECDSA over P-256." = 'Disable passkeys for this deployment, or move to a runtime whose crypto.subtle supports ECDSA over P-256.';

LCMS_OAUTH2_PASSKEY_ES256_UNAVAILABLE.risk ​

ts
readonly risk: "Passkey assertions cannot be verified at all, so WebAuthn logins would either always fail or would have to be accepted without verification." = 'Passkey assertions cannot be verified at all, so WebAuthn logins would either always fail or would have to be accepted without verification.';

LCMS_OAUTH2_PASSKEY_ES256_UNAVAILABLE.title ​

ts
readonly title: "SubtleCrypto cannot import or verify ECDSA P-256 (ES256) keys" = 'SubtleCrypto cannot import or verify ECDSA P-256 (ES256) keys';

LCMS_OAUTH2_PASSKEY_ES256_UNAVAILABLE.when ​

ts
readonly when: "first-request" = 'first-request';

LCMS_OAUTH2_PQ_PASSKEY_SIGNATURE ​

ts
readonly LCMS_OAUTH2_PQ_PASSKEY_SIGNATURE: object;

LCMS_OAUTH2_PQ_PASSKEY_SIGNATURE.detect ​

ts
readonly detect: (_probe, input) => boolean;
Parameters ​
ParameterType
_probeRuntimeProbe
inputGateInput
Returns ​

boolean

LCMS_OAUTH2_PQ_PASSKEY_SIGNATURE.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_PQ_PASSKEY_SIGNATURE.remedy ​

ts
readonly remedy: "Under this threat model, disable passkeys and authenticate with high-entropy secrets instead — or suppress this code only once you have decided passkey forgery is inside your risk appetite." = 'Under this threat model, disable passkeys and authenticate with high-entropy secrets instead — or suppress this code only once you have decided passkey forgery is inside your risk appetite.';

LCMS_OAUTH2_PQ_PASSKEY_SIGNATURE.risk ​

ts
readonly risk: "WebAuthn assertions are signed with ES256/RS256, both broken by Shor’s algorithm; a quantum-capable adversary forges passkey logins, and FIDO2 has no deployed post-quantum algorithm to migrate to." = 'WebAuthn assertions are signed with ES256/RS256, both broken by Shor’s algorithm; a quantum-capable adversary forges passkey logins, and FIDO2 has no deployed post-quantum algorithm to migrate to.';

LCMS_OAUTH2_PQ_PASSKEY_SIGNATURE.title ​

ts
readonly title: "Passkeys rely on Shor-breakable signatures under the post-quantum threat model" = 'Passkeys rely on Shor-breakable signatures under the post-quantum threat model';

LCMS_OAUTH2_PQ_PASSKEY_SIGNATURE.when ​

ts
readonly when: "construct" = 'construct';

LCMS_OAUTH2_PQ_PASSWORD_ONLY ​

ts
readonly LCMS_OAUTH2_PQ_PASSWORD_ONLY: object;

LCMS_OAUTH2_PQ_PASSWORD_ONLY.detect ​

ts
readonly detect: (_probe, input) => boolean;
Parameters ​
ParameterType
_probeRuntimeProbe
inputGateInput
Returns ​

boolean

LCMS_OAUTH2_PQ_PASSWORD_ONLY.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_PQ_PASSWORD_ONLY.remedy ​

ts
readonly remedy: "Enable TOTP or passkeys as a second factor so a recovered password is not sufficient on its own." = 'Enable TOTP or passkeys as a second factor so a recovered password is not sufficient on its own.';

LCMS_OAUTH2_PQ_PASSWORD_ONLY.risk ​

ts
readonly risk: "Grover’s algorithm halves effective password entropy, and traffic recorded today decrypts retroactively once a quantum adversary arrives — a harvested password alone then grants full access." = 'Grover’s algorithm halves effective password entropy, and traffic recorded today decrypts retroactively once a quantum adversary arrives — a harvested password alone then grants full access.';

LCMS_OAUTH2_PQ_PASSWORD_ONLY.title ​

ts
readonly title: "Password-only authentication under the post-quantum threat model" = 'Password-only authentication under the post-quantum threat model';

LCMS_OAUTH2_PQ_PASSWORD_ONLY.when ​

ts
readonly when: "construct" = 'construct';

LCMS_OAUTH2_PQ_TRANSPORT_UNVERIFIED ​

ts
readonly LCMS_OAUTH2_PQ_TRANSPORT_UNVERIFIED: object;

LCMS_OAUTH2_PQ_TRANSPORT_UNVERIFIED.detect ​

ts
readonly detect: (_probe, input) => boolean;
Parameters ​
ParameterType
_probeRuntimeProbe
inputGateInput
Returns ​

boolean

LCMS_OAUTH2_PQ_TRANSPORT_UNVERIFIED.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_PQ_TRANSPORT_UNVERIFIED.remedy ​

ts
readonly remedy: "Verify that your TLS termination negotiates a hybrid post-quantum key exchange (e.g. X25519MLKEM768). We cannot see that from here: suppressing this code IS your attestation that it does." = 'Verify that your TLS termination negotiates a hybrid post-quantum key exchange (e.g. X25519MLKEM768). We cannot see that from here: suppressing this code IS your attestation that it does.';

LCMS_OAUTH2_PQ_TRANSPORT_UNVERIFIED.risk ​

ts
readonly risk: "If your TLS termination does not negotiate a hybrid post-quantum key exchange, traffic recorded today — bearer tokens included — decrypts retroactively (harvest now, decrypt later)." = 'If your TLS termination does not negotiate a hybrid post-quantum key exchange, traffic recorded today — bearer tokens included — decrypts retroactively (harvest now, decrypt later).';

LCMS_OAUTH2_PQ_TRANSPORT_UNVERIFIED.title ​

ts
readonly title: "Post-quantum transport security cannot be verified from inside the process" = 'Post-quantum transport security cannot be verified from inside the process';

LCMS_OAUTH2_PQ_TRANSPORT_UNVERIFIED.when ​

ts
readonly when: "construct" = 'construct';

LCMS_OAUTH2_SHA256_UNAVAILABLE ​

ts
readonly LCMS_OAUTH2_SHA256_UNAVAILABLE: object;

LCMS_OAUTH2_SHA256_UNAVAILABLE.detect ​

ts
readonly detect: (probe) => Promise<boolean>;
Parameters ​
ParameterType
probeRuntimeProbe
Returns ​

Promise<boolean>

LCMS_OAUTH2_SHA256_UNAVAILABLE.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_SHA256_UNAVAILABLE.remedy ​

ts
readonly remedy: "Use a runtime whose crypto.subtle.digest supports SHA-256; do not substitute a JavaScript hash polyfill." = 'Use a runtime whose crypto.subtle.digest supports SHA-256; do not substitute a JavaScript hash polyfill.';

LCMS_OAUTH2_SHA256_UNAVAILABLE.risk ​

ts
readonly risk: "PKCE S256 challenges can neither be created nor verified — S256 is the only supported challenge method, and downgrading to \"plain\" would let an intercepting attacker replay authorization codes." = 'PKCE S256 challenges can neither be created nor verified — S256 is the only supported challenge method, and downgrading to "plain" would let an intercepting attacker replay authorization codes.';

LCMS_OAUTH2_SHA256_UNAVAILABLE.title ​

ts
readonly title: "SubtleCrypto cannot compute SHA-256 digests" = 'SubtleCrypto cannot compute SHA-256 digests';

LCMS_OAUTH2_SHA256_UNAVAILABLE.when ​

ts
readonly when: "first-request" = 'first-request';

LCMS_OAUTH2_WEBCRYPTO_SUBTLE_MISSING ​

ts
readonly LCMS_OAUTH2_WEBCRYPTO_SUBTLE_MISSING: object;

LCMS_OAUTH2_WEBCRYPTO_SUBTLE_MISSING.detect ​

ts
readonly detect: (probe) => boolean;
Parameters ​
ParameterType
probeRuntimeProbe
Returns ​

boolean

LCMS_OAUTH2_WEBCRYPTO_SUBTLE_MISSING.ignorable ​

ts
readonly ignorable: true = true;

LCMS_OAUTH2_WEBCRYPTO_SUBTLE_MISSING.remedy ​

ts
readonly remedy: "Run on a runtime that exposes crypto.subtle, or enable the embedding host’s native Web Crypto implementation instead of shimming it away." = 'Run on a runtime that exposes crypto.subtle, or enable the embedding host’s native Web Crypto implementation instead of shimming it away.';

LCMS_OAUTH2_WEBCRYPTO_SUBTLE_MISSING.risk ​

ts
readonly risk: "PKCE hashing, constant-time comparison, TOTP and passkey verification all bottom out in crypto.subtle; without it every cryptographic guarantee this package advertises is void." = 'PKCE hashing, constant-time comparison, TOTP and passkey verification all bottom out in crypto.subtle; without it every cryptographic guarantee this package advertises is void.';

LCMS_OAUTH2_WEBCRYPTO_SUBTLE_MISSING.title ​

ts
readonly title: "Web Crypto SubtleCrypto is unavailable (crypto.subtle)" = 'Web Crypto SubtleCrypto is unavailable (crypto.subtle)';

LCMS_OAUTH2_WEBCRYPTO_SUBTLE_MISSING.when ​

ts
readonly when: "construct" = 'construct';

Released under the MIT License.