Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions spec/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2723,6 +2723,11 @@ paths:
description: 'The credentials are not valid, or password sign-in is disabled for local accounts'
'429':
description: 'Too many failed attempts for this account'
headers:
Retry-After:
description: Whole seconds until the account may attempt a sign-in again
schema:
type: integer
'500':
description: 'An unexpected error occurred while signing in'
description: "Signs a user in with a username and password and starts a session.\n\nCredentials are checked against the local database or, for an account that\nauthenticates through LDAP, against the directory. A `401` is returned for\nunknown credentials, and also when password sign-in for local accounts is\ndisabled on the server.\n\nA `429` - the account is locked after repeated failures - carries a\n`Retry-After` header in seconds, so a client can show a countdown without\nparsing the message."
Expand Down
35 changes: 35 additions & 0 deletions spec/vendored-document.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { readFileSync } from 'node:fs'
import { join } from 'node:path'
import { parse } from 'yaml'

/**
* `check:routes` compares the route table derived from the vendored document,
* not the document itself, and the table carries no response headers. A header
* therefore survives a re-vendor only if the person copying the body notices
* it - which is how the sign-in lockout lost its `Retry-After`. These assertions
* name the facts the table cannot carry, so a copy that drops one fails here
* rather than in a consumer that had come to rely on it.
*/
const document = parse(readFileSync(join(__dirname, 'swagger.yaml'), 'utf8'))

describe('the vendored document', () => {
it('states the Retry-After header the sign-in lockout carries', () => {
const responses = document.paths['/SASLogon/login'].post.responses

expect(responses['429'].headers['Retry-After']).toEqual({
description:
'Whole seconds until the account may attempt a sign-in again',
schema: { type: 'integer' }
})
})

it('names the unit of that header in the operation description', () => {
const description = document.paths['/SASLogon/login'].post.description

// the prose is wrapped for the document, so compare it with the line breaks
// collapsed rather than pinning where they fall
expect(description.replace(/\s+/g, ' ')).toContain(
'carries a `Retry-After` header in seconds'
)
})
})
Loading