Answer prose round 1: 0 🔴, 5 🟡 (0 misread); cut the duplicated specificity line and reflow
CI / full-gate (push) Successful in 3m22s
CI / full-gate (push) Successful in 3m22s
This commit is contained in:
+3
-2
@@ -165,8 +165,9 @@ services:
|
|||||||
|
|
||||||
# Ory Hydra — OAuth2/OIDC provider (other apps log in *through* plainpages; README).
|
# Ory Hydra — OAuth2/OIDC provider (other apps log in *through* plainpages; README).
|
||||||
# DSN is its own `hydra` DB (init.sql); config in ory/hydra/hydra.yml. web implements the
|
# DSN is its own `hydra` DB (init.sql); config in ory/hydra/hydra.yml. web implements the
|
||||||
# login challenge at /oauth2/login and the consent challenge at /oauth2/consent. Dev permits the http issuer via --dev
|
# login challenge at /oauth2/login and the consent challenge at /oauth2/consent. Dev permits the
|
||||||
# (compose.override.yml); prod sets an https issuer via env (URLS_SELF_ISSUER).
|
# http issuer via --dev (compose.override.yml); prod sets an https issuer via env
|
||||||
|
# (URLS_SELF_ISSUER).
|
||||||
hydra-migrate:
|
hydra-migrate:
|
||||||
image: oryd/hydra:v26.2.0
|
image: oryd/hydra:v26.2.0
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ const GROUP_NS = "Group";
|
|||||||
const MEMBERS = "members";
|
const MEMBERS = "members";
|
||||||
const DEFAULT_PAGE_SIZE = 25;
|
const DEFAULT_PAGE_SIZE = 25;
|
||||||
const PAGE_SIZES = [25, 50, 100];
|
const PAGE_SIZES = [25, 50, 100];
|
||||||
// One Kratos `listIdentities` page of candidate users is fetched for the member pickers (mirrors admin-users).
|
// One Kratos `listIdentities` page of candidate users is fetched for the member pickers (mirrors
|
||||||
|
// admin-users).
|
||||||
const LIST_FETCH_SIZE = 250;
|
const LIST_FETCH_SIZE = 250;
|
||||||
const GROUP_NAME = /^[a-z0-9][a-z0-9_-]*$/; // URL-safe; doubles as the path segment
|
const GROUP_NAME = /^[a-z0-9][a-z0-9_-]*$/; // URL-safe; doubles as the path segment
|
||||||
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; // a Kratos identity id
|
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; // a Kratos identity id
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ export default definePlugin({
|
|||||||
public: true, // the header gates nothing; each child names its own gate, and an empty header is dropped
|
public: true, // the header gates nothing; each child names its own gate, and an empty header is dropped
|
||||||
}],
|
}],
|
||||||
|
|
||||||
// Permissions this plugin declares (docs + Keto seeding), named `<resource>:<action>`.
|
// Permissions this plugin declares: the admin picker offers them and bootstrap grants them to the demo admin.
|
||||||
permissions: [
|
permissions: [
|
||||||
{ description: "View shifts", name: READ },
|
{ description: "View shifts", name: READ },
|
||||||
{ description: "Create and edit shifts", name: WRITE },
|
{ description: "Create and edit shifts", name: WRITE },
|
||||||
|
|||||||
@@ -20,10 +20,11 @@
|
|||||||
resolution is unreliable across engines. color-scheme is still
|
resolution is unreliable across engines. color-scheme is still
|
||||||
set as a hint for native widgets (date picker, scrollbars,
|
set as a hint for native widgets (date picker, scrollbars,
|
||||||
selects).
|
selects).
|
||||||
Footgun: a token value a floor engine can't parse (a function or unit it lacks)
|
Footgun: a token value an engine of the oldest browser floor can't parse (a
|
||||||
is invalid at computed-value time, so every declaration reading it through
|
function or unit it lacks) is invalid at computed-value time, so every
|
||||||
var() computes as `unset`; a fallback declared before it doesn't help.
|
declaration reading it through var() computes as `unset`; a fallback declared
|
||||||
src/test-tooling/stylesheet-floor.ts fails its test on one.
|
before it doesn't help. The test in src/test-tooling/stylesheet-floor.ts
|
||||||
|
fails on such a value.
|
||||||
------------------------------------------------------------- */
|
------------------------------------------------------------- */
|
||||||
:root {
|
:root {
|
||||||
/* ---- raw LIGHT palette ---- */
|
/* ---- raw LIGHT palette ---- */
|
||||||
|
|||||||
+2
-3
@@ -4,9 +4,8 @@ import type { JsonWebKey } from "./jwks.ts";
|
|||||||
|
|
||||||
// JWS signature verification with the Node stdlib — no `jose`/JWT dep:
|
// JWS signature verification with the Node stdlib — no `jose`/JWT dep:
|
||||||
// `createPublicKey({format:"jwk"})` imports a JWK and verifies the RS*/ES* signatures
|
// `createPublicKey({format:"jwk"})` imports a JWK and verifies the RS*/ES* signatures
|
||||||
// the Kratos tokenizer produces (see AGENTS.md). Signature only: the caller
|
// the Kratos tokenizer produces. Signature only: `jwt-middleware.ts`
|
||||||
// (`jwt-middleware.ts`) adds claim checks (exp/iss/aud, clock skew) and picks the key by `kid`
|
// picks the key by `kid` and checks the claims.
|
||||||
// from the cached JWKS (`jwks.ts` fetches and rotates it).
|
|
||||||
|
|
||||||
// JOSE `alg` → Node verify parameters. ES* signatures are raw r‖s (IEEE P1363), not DER.
|
// JOSE `alg` → Node verify parameters. ES* signatures are raw r‖s (IEEE P1363), not DER.
|
||||||
// Extend this map to widen support. Security invariant: never add `HS*`/`none` — this map
|
// Extend this map to widen support. Security invariant: never add `HS*`/`none` — this map
|
||||||
|
|||||||
+2
-2
@@ -40,8 +40,8 @@ export interface CompletedLogin {
|
|||||||
// The coarse permissions a user holds — directly (`Permission:<name>#granted@user:<id>`) or transitively via a
|
// The coarse permissions a user holds — directly (`Permission:<name>#granted@user:<id>`) or transitively via a
|
||||||
// group granted the permission. Enumerates the defined permissions (the distinct objects in the Permission
|
// group granted the permission. Enumerates the defined permissions (the distinct objects in the Permission
|
||||||
// namespace) and asks Keto to check each grant, so a permission granted to a group reaches the JWT —
|
// namespace) and asks Keto to check each grant, so a permission granted to a group reaches the JWT —
|
||||||
// matching the OPL model. At login/refresh only, never per
|
// matching the OPL model. At login/refresh only, never per request; permission count is small, so the
|
||||||
// request; permission count is small, so the per-permission checks are cheap and run in parallel.
|
// per-permission checks are cheap and run in parallel.
|
||||||
export async function readPermissions(keto: KetoClient, userId: string): Promise<string[]> {
|
export async function readPermissions(keto: KetoClient, userId: string): Promise<string[]> {
|
||||||
const subject_id = `user:${userId}`;
|
const subject_id = `user:${userId}`;
|
||||||
const names = new Set<string>();
|
const names = new Set<string>();
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
// Router: pure core mapping method + pathname → a discovered plugin route. I/O-free;
|
// Router: pure core mapping method + pathname → a discovered plugin route. I/O-free;
|
||||||
// app.ts is the shell (build context, gate, call handler, render RouteResult). A route mounts at
|
// app.ts is the shell (build context, gate, call handler, render RouteResult). A route mounts at
|
||||||
// `/<id>` + its path (fullPath, shared with conflict detection); `:name` segments → path params.
|
// `/<id>` + its path (fullPath, shared with conflict detection); `:name` segments → path params.
|
||||||
// Specificity: the route with fewer `:param` segments wins (/users/new beats /users/:id). A tie, such
|
|
||||||
// as /a/:x/b against /a/b/:y, falls to discovery order.
|
|
||||||
|
|
||||||
import { fullPath, type Plugin, type Route } from "./plugin.ts";
|
import { fullPath, type Plugin, type Route } from "./plugin.ts";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user