fix(skatteverket): stop classifying the APIGW scope-contract 403 as MISSING_SCOPE (#1250)
* fix(skatteverket): stop classifying the APIGW scope-contract 403 as MISSING_SCOPE
The user-mode 403 branch matched the substring `required scope`, which also
matches the MuleSoft APIGW contract body `{"error": "The required scopes are
not authorized"}`. That body is a subscription gap on our APIGW client (#973),
decided before the bearer is evaluated, so it says nothing about the user's
token. Calling it MISSING_SCOPE put it in RECONSENT_ERROR_CODES, so a
successful reconnect ran runPostConnectRefresh -> syncSkattekonto -> 403 and
instantly re-flagged the row: the reconnect banner perpetuated itself and no
amount of reconnecting could clear it.
Token-scope detection is now a positive match on the two documented shapes
(the OAuth `invalid_scope` code, and SKV's "The required scope <x> has been
requested for that access token." per AGI Tjänstebeskrivning v1.7 §4.1.2.2).
The gateway signature is checked first and maps to ACCESS_DENIED, which is
deliberately not a reconsent code. System mode keeps SYSTEM_AUTH_FAILED for
both (run-level config either way) but no longer points the operator at
SKATTEVERKET_SYSTEM_SCOPES when the gateway is what refused, and the same
wording on a 401 now joins the existing APIGW branch instead of falling
through to SESSION_EXPIRED (also a reconsent code).
Refs #1155 (item 1), #973
* fix(skatteverket): let the gateway signature win over the OAuth challenge header on 401
Review follow-up: the 401 path checked WWW-Authenticate for invalid_scope
before looking at the body, so a MuleSoft contract error arriving with an
OAuth-shaped challenge header would still be classified MISSING_SCOPE. Both
that and SESSION_EXPIRED are reconsent codes, so either verdict re-arms the
banner the user just tried to clear.
The gateway body check now runs first, mirroring the 403 path, and the
redundant entry in looksLikeApigwIssue is gone. The 401 test carries the
challenge header to pin the precedence.
This commit is contained in:
@@ -626,3 +626,4 @@ One line per decision: `[YYYY-MM-DD] <decision>: <why>`. Appended by agents and
|
||||
[2026-07-27] support_feedback_submitted now reports BOTH channels (email + ticket) with a derived `lost` flag, not just email delivery. Both channels fail silently from the user's side: email is the guarantee so the UI still shows success when only the ticket failed, and a ticket that never opened leaves nothing in PostHog Support to look at either. Answering "did the ticket open?" previously required reproducing it with devtools open, which is exactly what happened the first time Support shipped. ticket: 'unavailable' is kept distinct from 'failed' because unavailable is the expected steady state (Support off, analytics off) while failed means conversations were live and the call still did not land; only the second is worth alerting on. `lost` (neither channel worked) is the single property to alert on. Still carries no message body, pinned by a test.
|
||||
[2026-07-27] support_feedback_submitted reports both channels (email + ticket) with a derived `lost` flag, and the ticket call runs concurrently with a 4s cap instead of being awaited after the email: both channels fail silently from the user's side, so "did the ticket open?" was previously only answerable by reproducing the submission with devtools open, and awaiting the ticket sequentially let a hung sendMessage hold the confirmation dialog open despite the code comment claiming it could not. ticket: 'unavailable' stays distinct from 'failed' and 'timeout' because unavailable is the expected steady state (Support off, analytics off, self-hosted) while the other two mean conversations were live and the call still did not land; only those deserve an alert. `lost` (neither channel worked) is the single property to alert on. Still carries no message body, pinned by a test.
|
||||
[2026-07-27] Supplier-invoice edits (#1230): block invoice_date / supplier_invoice_number once registration_journal_entry_id is set, rather than propagating the change into the verifikat via correct_entry_metadata: the friendlier propagate option turns a metadata PUT into a bookkeeping write (voucher rättelse, rattelse-log, period-lock checks) and needs a deliberate product call; blocking is the minimal legally correct behaviour and leaves due_date/payment_reference/notes editable for the aged-invoice flow (#1206).
|
||||
[2026-07-27] SKV 403 classification (#1155 item 1): the MuleSoft APIGW body "The required scopes are not authorized" is checked BEFORE the token-scope patterns and maps to ACCESS_DENIED (user mode) / SYSTEM_AUTH_FAILED with a subscription message (system mode). Substring matching on 'required scope' collided with it and produced MISSING_SCOPE, which is a RECONSENT code, so every reconnect re-flagged the token row. Token-scope detection is now a positive match on invalid_scope or SKV's documented "required scope <x> has been requested" sentence, not a loose substring.
|
||||
|
||||
Reference in New Issue
Block a user