You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wiki/backend/api/schemas/authentication.ts

190 lines
5.4 KiB

import type { FastifyInstance } from 'fastify'
export async function registerSchemas(app: FastifyInstance): Promise<void> {
/**
* AUTH LOGIN RESULT - Where a login attempt got to, and what the client must do next
*/
app.addSchema({
$id: 'AuthLoginResult',
type: 'object',
properties: {
ok: {
type: 'boolean'
},
authenticated: {
type: 'boolean',
description: 'Present, and true, only once the session is actually logged in.'
},
nextAction: {
type: 'string',
enum: ['redirect', 'changePassword', 'provideTfa', 'setupTfa'],
description:
'What the client has to do to finish. Anything other than `redirect` means the attempt is not a login yet and has to be continued with `continuationToken`.'
},
continuationToken: {
type: 'string',
description: 'Stands for this half-finished login. Sent back with whatever it asked for.'
},
tfaQRImage: {
type: 'string',
description:
'For `setupTfa` only: the `otpauth://` URI as an SVG QR code, to be rendered as-is.'
},
redirect: {
type: 'string',
description: 'Where to send the user once logged in. A path within this wiki, or a URL.'
}
}
})
/**
* AUTH MODULE - An authentication module as found on disk
*/
app.addSchema({
$id: 'AuthModule',
type: 'object',
properties: {
key: {
type: 'string',
description: 'Directory name under `modules/authentication`.'
},
title: {
type: 'string'
},
description: {
type: 'string'
},
logo: {
type: 'string'
},
icon: {
type: 'string'
},
color: {
type: 'string'
},
vendor: {
type: 'string'
},
website: {
type: 'string'
},
isAvailable: {
type: 'boolean'
},
useForm: {
type: 'boolean',
description: 'Whether logging in through it means submitting a username and password.'
},
usernameType: {
type: 'string'
},
props: {
type: 'object',
additionalProperties: true,
description:
'The module configuration, declared in its `definition.yml`: each entry carries a `type`, `title`, `hint`, `default` and the display hints the admin area renders a control from. A `readOnly` prop is shown but cannot be changed, and is silently kept at its stored value when written to.'
},
refs: {
type: 'object',
additionalProperties: true,
description:
'Read-only values the administrator needs to configure the other side, such as a callback URL. `{host}` and `{id}` are placeholders for the wiki origin and the strategy ID.'
}
}
})
/**
* AUTH STRATEGY - A configured instance of a module
*/
app.addSchema({
$id: 'AuthStrategy',
type: 'object',
properties: {
id: {
type: 'string',
format: 'uuid'
},
module: {
type: 'string',
description: 'Key of the module this strategy is an instance of.'
},
displayName: {
type: 'string'
},
isEnabled: {
type: 'boolean'
},
registration: {
type: 'boolean'
},
allowedEmailRegex: {
type: 'string'
},
autoEnrollGroups: {
type: 'array',
items: {
type: 'string',
format: 'uuid'
}
},
config: {
type: 'object',
additionalProperties: true,
description:
'Values for the module props, completed with the module defaults for any prop that has none stored yet.'
}
}
})
/**
* AUTH STRATEGY INPUT - Used both ways: to create a strategy, and as a partial update
*/
app.addSchema({
$id: 'AuthStrategyInput',
type: 'object',
properties: {
module: {
type: 'string',
maxLength: 255,
description:
'Only on create, and only a module that exists on disk. Cannot be changed after.'
},
displayName: {
type: 'string',
maxLength: 255,
description: 'Defaults to the module title on create.'
},
isEnabled: {
type: 'boolean'
},
registration: {
type: 'boolean',
description:
'Whether an account is created for somebody signing in for the first time. Enforced for the providers that sign users in elsewhere (OpenID Connect, Google, GitHub); the local module has a registration flow of its own.'
},
allowedEmailRegex: {
type: 'string',
maxLength: 255,
description:
'Must be a valid regular expression. Limits which addresses an account may be created for, and applies where registration does — a pattern that will not compile allows nobody.'
},
autoEnrollGroups: {
type: 'array',
items: {
type: 'string',
format: 'uuid'
},
description:
'Groups a self-registered user would join. The guests group is refused. Stored but not enforced, as above.'
},
config: {
type: 'object',
additionalProperties: true,
description:
'Values for the module props. Validated against what the module declares: an unknown key is dropped, a wrong type is refused, and a read-only prop keeps its stored value.'
}
}
})
}