-
Notifications
You must be signed in to change notification settings - Fork 57
/
express-basic-auth.d.ts
151 lines (133 loc) · 5.87 KB
/
express-basic-auth.d.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/// <reference types="express" />
import { Request, RequestHandler } from 'express'
/**
* This is the middleware builder.
*
* Example:
* const users = { alice: '1234', bob: 'correcthorsebatterystaple' }
* app.use(basicAuth({ users, challenge: true }), myHandler)
*
* @param options The middleware's options (at least 'users' or 'authorizer' are mandatory).
*/
declare function expressBasicAuth(options: expressBasicAuth.BasicAuthMiddlewareOptions): RequestHandler
declare namespace expressBasicAuth {
/**
* Time safe string comparison function to protect against timing attacks.
*
* It is important to provide the arguments in the correct order, as the runtime
* depends only on the `userInput` argument. Switching the order would expose the `secret`
* to timing attacks.
*
* @param userInput The user input to be compared
* @param secret The secret value the user input should be compared with
*
* @returns true if `userInput` matches `secret`, false if not
*/
export function safeCompare(userInput: string, secret: string): boolean
/**
* The configuration you pass to the middleware can take three forms, either:
* - A map of static users ({ bob: 'pa$$w0rd', ... }) ;
* - An authorizer function
* - An asynchronous authorizer function
*/
export type BasicAuthMiddlewareOptions = IUsersOptions | (IAuthorizerOptions | IAsyncAuthorizerOptions)
/**
* express-basic-auth patches the request object to set an `auth` property that lets you retrieve the authed user.
*
* Example (TypeScript):
* app.use(basicAuth({ ... }), (req: basicAuth.IBasicAuthedRequest, res, next) => {
* res.end(`Welcome ${req.auth.user} (your password is ${req.auth.password})`)
* next()
* })
*/
export interface IBasicAuthedRequest extends Request {
auth: { user: string, password: string }
}
type Authorizer = (username: string, password: string) => boolean
type AsyncAuthorizerCallback = (err: any, authed?: boolean) => void
type AsyncAuthorizer = (username: string, password: string, callback: AsyncAuthorizerCallback) => void
type ValueOrFunction<T> = T | ((req: IBasicAuthedRequest) => T)
interface IBaseOptions {
/**
* Per default the middleware will not add a WWW-Authenticate challenge header to responses of unauthorized requests.
* You can enable that by setting this to true, causing most browsers to show a popup to enter credentials
* on unauthorized responses.
*
* @default false
*/
challenge?: boolean
/**
* You can set the realm (the realm identifies the system to authenticate against and can be used by clients to
* save credentials) of the challenge by passing a string or a function that gets passed the request and is
* expected to return the realm.
*
* @default undefined
*/
realm?: ValueOrFunction<string>
/**
* Per default, the response body for unauthorized responses will be empty.
* It can be configured using the unauthorizedResponse option. You can either pass a static response or a
* function that gets passed the express request object and is expected to return the response body.
* If the response body is a string, it will be used as-is, otherwise it will be sent as JSON.
*
* @default ''
*/
unauthorizedResponse?: ValueOrFunction<any>
}
interface IUsersOptions extends IBaseOptions {
/**
* If you simply want to check basic auth against one or multiple static credentials, you can pass those
* credentials in the users option.
*
* Example:
* const users = { alice: '1234', bob: 'correcthorsebatterystaple' }
* app.use(basicAuth({ users, challenge: true }), myHandler)
*/
users: { [username: string]: string }
}
interface IAuthorizerOptions extends IBaseOptions {
/**
* Set to true if your authorizer is asynchronous.
*/
authorizeAsync?: false
/**
* You can pass your own authorizer function, to check the credentials however you want.
* It will be called with a username and password and is expected to return true or false to indicate that the
* credentials were approved or not:
*
* Example:
* app.use(basicAuth({ authorizer }))
*
* function myAuthorizer(username: string, password: string) {
* return username.startsWith('A') && password.startsWith('secret');
* }
*
* This will authorize all requests with credentials where the username begins with 'A' and the password begins
* with 'secret'. In an actual application you would likely look up some data instead ;-)
*/
authorizer: Authorizer
}
interface IAsyncAuthorizerOptions extends IBaseOptions {
/**
* Set it to true to use a asynchronous authorizer.
*/
authorizeAsync: true
/**
* You can pass an asynchronous authorizer. It will be passed a callback as the third parameter, which is
* expected to be called by standard node convention with an error and a boolean to indicate if the credentials
* have been approved or not.
*
* Example:
* app.use(basicAuth({ authorizer, authorizeAsync: true }));
*
* function authorizer(username, password, authorize) {
* if(username.startsWith('A') && password.startsWith('secret'))
* return authorize(null, true)
*
* return authorize(null, false)
* }
*/
authorizer: AsyncAuthorizer
}
}
export = expressBasicAuth