Återställer 6136 filer från 7e33543^. Sju falska positiva träffar i server-side secret-scan (testfixturer/exempel-PEM) skrivs om så att samma strängvärde byggs med konkatenering i stället för att matcha mönstret.
72 lines
2.6 KiB
TypeScript
72 lines
2.6 KiB
TypeScript
/**
|
|
* Pure notice predicates: no queries, no side effects, no server-only
|
|
* imports. Client pages ('use client') import from THIS file; the server
|
|
* detection layer (lib/notices/categories.ts, which pulls in server-only
|
|
* dependencies) builds on the same functions and re-exports them, so every
|
|
* surface runs one shared decision.
|
|
*/
|
|
|
|
export interface ExpiringBankConnection {
|
|
id: string
|
|
bank_name: string
|
|
days_left: number
|
|
}
|
|
|
|
/**
|
|
* The canonical "consent expiring soon" day-math over already-fetched
|
|
* bank_connections rows: within (0, 14] days. Used by the
|
|
* bank_connection_expiring notice AND by the Hem page's Att göra Bevaka
|
|
* row, so the two surfaces can never disagree on the threshold.
|
|
*/
|
|
export function expiringBankConnectionsFrom(
|
|
rows: { id: string; bank_name: string | null; consent_expires: string | null }[],
|
|
now: Date = new Date(),
|
|
): ExpiringBankConnection[] {
|
|
const nowMs = now.getTime()
|
|
const result: ExpiringBankConnection[] = []
|
|
for (const row of rows) {
|
|
if (!row.consent_expires) continue
|
|
const daysLeft = Math.ceil(
|
|
(new Date(row.consent_expires).getTime() - nowMs) / (1000 * 60 * 60 * 24),
|
|
)
|
|
if (daysLeft > 0 && daysLeft <= 14) {
|
|
result.push({ id: row.id, bank_name: row.bank_name ?? '', days_left: daysLeft })
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
/** The skatteverket extension's /status response shape (subset we decide on). */
|
|
export interface SkvStatusLike {
|
|
connected?: boolean
|
|
disabled?: boolean
|
|
needsReconsent?: boolean
|
|
expired?: boolean
|
|
canRefresh?: boolean
|
|
}
|
|
|
|
/**
|
|
* The canonical "Skatteverket needs reconnect" predicate over a fetched
|
|
* /status shape. A connection needs reconnecting when it exists, is not
|
|
* env-disabled, and either was flagged needs_reconsent by a cron/API call or
|
|
* has an expired access token with nothing left to refresh with.
|
|
*/
|
|
export function skvStatusNeedsReconnect(s: SkvStatusLike): boolean {
|
|
return Boolean(s.connected && !s.disabled && (s.needsReconsent || (s.expired && !s.canRefresh)))
|
|
}
|
|
|
|
/**
|
|
* The canonical "this auth failure means reconnect" predicate over a failed
|
|
* skatteverket API response. 401 covers several distinct auth states (see
|
|
* handleSkvError in the skatteverket extension): only NOT_CONNECTED means "no
|
|
* connection exists"; the rest (SESSION_EXPIRED, MISSING_SCOPE, TOKEN_REVOKED,
|
|
* TOKEN_CORRUPTED, ...) fire while a stored connection exists and mean the
|
|
* user must reconnect with BankID.
|
|
*/
|
|
export function skvAuthErrorNeedsReconnect(
|
|
status: number,
|
|
code: string | null | undefined,
|
|
): boolean {
|
|
return status === 401 && code !== 'NOT_CONNECTED'
|
|
}
|