Define and validate restored-session setup state
This commit is contained in:
@@ -14,6 +14,13 @@ jobs:
|
|||||||
node-version: 22
|
node-version: 22
|
||||||
- name: Validate repository documentation
|
- name: Validate repository documentation
|
||||||
run: test -f README.md && test -f AGENTS.md && test -f docs/versioning.md
|
run: test -f README.md && test -f AGENTS.md && test -f docs/versioning.md
|
||||||
|
- uses: actions/setup-python@v5
|
||||||
|
with:
|
||||||
|
python-version: '3.12'
|
||||||
|
- name: Validate restored-session schema and negative cases
|
||||||
|
run: |
|
||||||
|
python -m pip install jsonschema==4.26.0
|
||||||
|
python tests/session_contract.py
|
||||||
- name: Validate JSON contracts and fixtures
|
- name: Validate JSON contracts and fixtures
|
||||||
run: |
|
run: |
|
||||||
node --input-type=module <<'NODE'
|
node --input-type=module <<'NODE'
|
||||||
|
|||||||
@@ -16,6 +16,11 @@ request and response envelopes; bearer values in fixtures are synthetic only.
|
|||||||
Twitch OAuth link and completion response envelopes are also versioned here;
|
Twitch OAuth link and completion response envelopes are also versioned here;
|
||||||
fixtures contain no real credentials or tokens.
|
fixtures contain no real credentials or tokens.
|
||||||
|
|
||||||
|
`GET /api/v1/auth/session` returns `authenticated: true` and the current
|
||||||
|
`must_replace_credentials` flag from the administrator account. Restoring a
|
||||||
|
session must not bypass first-run setup. Older servers omit this flag; clients
|
||||||
|
must not interpret an absent flag as completed credential replacement.
|
||||||
|
|
||||||
The shared boundary vocabulary includes the ordered permission levels in
|
The shared boundary vocabulary includes the ordered permission levels in
|
||||||
`contracts/v1/permissions.json` and the client/server compatibility result in
|
`contracts/v1/permissions.json` and the client/server compatibility result in
|
||||||
`contracts/v1/version-negotiation.json`. Server-owned state is delivered as
|
`contracts/v1/version-negotiation.json`. Server-owned state is delivered as
|
||||||
@@ -49,4 +54,3 @@ only synthetic Twitch IDs and literal response templates.
|
|||||||
|
|
||||||
Typed command arguments use `bot-command-argument-definition.json` and remain
|
Typed command arguments use `bot-command-argument-definition.json` and remain
|
||||||
literal validated data.
|
literal validated data.
|
||||||
|
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
"title": "Trixie Session Response",
|
"title": "Trixie Session Response",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"required": ["authenticated"],
|
"required": ["authenticated", "must_replace_credentials"],
|
||||||
"properties": {
|
"properties": {
|
||||||
"authenticated": { "const": true }
|
"authenticated": { "const": true },
|
||||||
|
"must_replace_credentials": { "type": "boolean" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,3 +16,11 @@ than in a URL query parameter. The server closes the connection when the frame
|
|||||||
is missing, malformed, or invalid, and sends `connection.ready` only after
|
is missing, malformed, or invalid, and sends `connection.ready` only after
|
||||||
successful validation.
|
successful validation.
|
||||||
|
|
||||||
|
The restored-session contract has Draft 2020-12 validation for both credential
|
||||||
|
replacement states, missing fields, wrong types, and unexpected properties:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
uv run --with jsonschema==4.26.0 python tests/session_contract.py
|
||||||
|
```
|
||||||
|
|
||||||
|
This isolated validation dependency is tooling only, not an application dependency.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
{
|
{
|
||||||
"authenticated": true
|
"authenticated": true,
|
||||||
|
"must_replace_credentials": false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"authenticated": true,
|
||||||
|
"must_replace_credentials": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
"""Validate restored-session fixtures and rejection cases against Draft 2020-12."""
|
||||||
|
|
||||||
|
import json
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from jsonschema import Draft202012Validator
|
||||||
|
|
||||||
|
root = Path(__file__).resolve().parents[1]
|
||||||
|
schema = json.loads((root / "contracts/v1/auth-session-response.json").read_text())
|
||||||
|
Draft202012Validator.check_schema(schema)
|
||||||
|
validator = Draft202012Validator(schema)
|
||||||
|
|
||||||
|
for name in ["auth-session.authenticated.json", "auth-session.bootstrap.json"]:
|
||||||
|
validator.validate(json.loads((root / "fixtures/v1" / name).read_text()))
|
||||||
|
|
||||||
|
for invalid in [
|
||||||
|
{"authenticated": True},
|
||||||
|
{"authenticated": False, "must_replace_credentials": False},
|
||||||
|
{"authenticated": True, "must_replace_credentials": "false"},
|
||||||
|
{"authenticated": True, "must_replace_credentials": False, "unexpected": True},
|
||||||
|
]:
|
||||||
|
assert not validator.is_valid(invalid), "Invalid session response was accepted"
|
||||||
|
|
||||||
|
print("Session schema: two valid fixtures and four rejection cases passed")
|
||||||
Reference in New Issue
Block a user