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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
|
import { MatrixClient } from "./client";
export interface UIAFlow {
stages: AuthType[];
}
export interface IInputs {
emailAddress?: string;
phoneCountry?: string;
phoneNumber?: string;
registrationToken?: string;
}
export interface IStageStatus {
emailSid?: string;
errcode?: string;
error?: string;
}
export interface IAuthData {
session?: string;
type?: string;
completed?: string[];
flows?: UIAFlow[];
available_flows?: UIAFlow[];
stages?: string[];
required_stages?: AuthType[];
params?: Record<string, Record<string, any>>;
data?: Record<string, string>;
errcode?: string;
error?: string;
user_id?: string;
device_id?: string;
access_token?: string;
}
export declare enum AuthType {
Password = "m.login.password",
Recaptcha = "m.login.recaptcha",
Terms = "m.login.terms",
Email = "m.login.email.identity",
Msisdn = "m.login.msisdn",
Sso = "m.login.sso",
SsoUnstable = "org.matrix.login.sso",
Dummy = "m.login.dummy",
RegistrationToken = "m.login.registration_token",
UnstableRegistrationToken = "org.matrix.msc3231.login.registration_token"
}
export interface IAuthDict {
type?: string;
session?: string;
user?: string;
identifier?: any;
password?: string;
response?: string;
threepid_creds?: any;
threepidCreds?: any;
token?: string;
}
interface IOpts {
/**
* A matrix client to use for the auth process
*/
matrixClient: MatrixClient;
/**
* Error response from the last request. If null, a request will be made with no auth before starting.
*/
authData?: IAuthData;
/**
* Inputs provided by the user and used by different stages of the auto process.
* The inputs provided will affect what flow is chosen.
*/
inputs?: IInputs;
/**
* If resuming an existing interactive auth session, the sessionId of that session.
*/
sessionId?: string;
/**
* If resuming an existing interactive auth session, the client secret for that session
*/
clientSecret?: string;
/**
* If returning from having completed m.login.email.identity auth, the sid for the email verification session.
*/
emailSid?: string;
/**
* Called with the new auth dict to submit the request.
* Also passes a second deprecated arg which is a flag set to true if this request is a background request.
* The busyChanged callback should be used instead of the background flag.
* Should return a promise which resolves to the successful response or rejects with a MatrixError.
*/
doRequest(auth: IAuthData | null, background: boolean): Promise<IAuthData>;
/**
* Called when the status of the UI auth changes,
* ie. when the state of an auth stage changes of when the auth flow moves to a new stage.
* The arguments are: the login type (eg m.login.password); and an object which is either an error or an
* informational object specific to the login type.
* If the 'errcode' key is defined, the object is an error, and has keys:
* errcode: string, the textual error code, eg. M_UNKNOWN
* error: string, human readable string describing the error
*
* The login type specific objects are as follows:
* m.login.email.identity:
* * emailSid: string, the sid of the active email auth session
*/
stateUpdated(nextStage: AuthType, status: IStageStatus): void;
/**
* A function that takes the email address (string), clientSecret (string), attempt number (int) and
* sessionId (string) and calls the relevant requestToken function and returns the promise returned by that
* function.
* If the resulting promise rejects, the rejection will propagate through to the attemptAuth promise.
*/
requestEmailToken(email: string, secret: string, attempt: number, session: string): Promise<{
sid: string;
}>;
/**
* Called whenever the interactive auth logic becomes busy submitting information provided by the user or finishes.
* After this has been called with true the UI should indicate that a request is in progress
* until it is called again with false.
*/
busyChanged?(busy: boolean): void;
startAuthStage?(nextStage: string): Promise<void>;
}
/**
* Abstracts the logic used to drive the interactive auth process.
*
* <p>Components implementing an interactive auth flow should instantiate one of
* these, passing in the necessary callbacks to the constructor. They should
* then call attemptAuth, which will return a promise which will resolve or
* reject when the interactive-auth process completes.
*
* <p>Meanwhile, calls will be made to the startAuthStage and doRequest
* callbacks, and information gathered from the user can be submitted with
* submitAuthDict.
*
* @param opts - options object
*/
export declare class InteractiveAuth {
private readonly matrixClient;
private readonly inputs;
private readonly clientSecret;
private readonly requestCallback;
private readonly busyChangedCallback?;
private readonly stateUpdatedCallback;
private readonly requestEmailTokenCallback;
private data;
private emailSid?;
private requestingEmailToken;
private attemptAuthDeferred;
private chosenFlow;
private currentStage;
private emailAttempt;
private submitPromise;
constructor(opts: IOpts);
/**
* begin the authentication process.
*
* @returns which resolves to the response on success,
* or rejects with the error on failure. Rejects with NoAuthFlowFoundError if
* no suitable authentication flow can be found
*/
attemptAuth(): Promise<IAuthData>;
/**
* Poll to check if the auth session or current stage has been
* completed out-of-band. If so, the attemptAuth promise will
* be resolved.
*/
poll(): Promise<void>;
/**
* get the auth session ID
*
* @returns session id
*/
getSessionId(): string | undefined;
/**
* get the client secret used for validation sessions
* with the identity server.
*
* @returns client secret
*/
getClientSecret(): string;
/**
* get the server params for a given stage
*
* @param loginType - login type for the stage
* @returns any parameters from the server for this stage
*/
getStageParams(loginType: string): Record<string, any> | undefined;
getChosenFlow(): UIAFlow | null;
/**
* submit a new auth dict and fire off the request. This will either
* make attemptAuth resolve/reject, or cause the startAuthStage callback
* to be called for a new stage.
*
* @param authData - new auth dict to send to the server. Should
* include a `type` property denoting the login type, as well as any
* other params for that stage.
* @param background - If true, this request failing will not result
* in the attemptAuth promise being rejected. This can be set to true
* for requests that just poll to see if auth has been completed elsewhere.
*/
submitAuthDict(authData: IAuthDict, background?: boolean): Promise<void>;
/**
* Gets the sid for the email validation session
* Specific to m.login.email.identity
*
* @returns The sid of the email auth session
*/
getEmailSid(): string | undefined;
/**
* Sets the sid for the email validation session
* This must be set in order to successfully poll for completion
* of the email validation.
* Specific to m.login.email.identity
*
* @param sid - The sid for the email validation session
*/
setEmailSid(sid: string): void;
/**
* Requests a new email token and sets the email sid for the validation session
*/
requestEmailToken: () => Promise<void>;
/**
* Fire off a request, and either resolve the promise, or call
* startAuthStage.
*
* @internal
* @param auth - new auth dict, including session id
* @param background - If true, this request is a background poll, so it
* failing will not result in the attemptAuth promise being rejected.
* This can be set to true for requests that just poll to see if auth has
* been completed elsewhere.
*/
private doRequest;
/**
* Pick the next stage and call the callback
*
* @internal
* @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
*/
private startNextAuthStage;
/**
* Pick the next auth stage
*
* @internal
* @returns login type
* @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
*/
private chooseStage;
/**
* Pick one of the flows from the returned list
* If a flow using all of the inputs is found, it will
* be returned, otherwise, null will be returned.
*
* Only flows using all given inputs are chosen because it
* is likely to be surprising if the user provides a
* credential and it is not used. For example, for registration,
* this could result in the email not being used which would leave
* the account with no means to reset a password.
*
* @internal
* @returns flow
* @throws {@link NoAuthFlowFoundError} If no suitable authentication flow can be found
*/
private chooseFlow;
/**
* Get the first uncompleted stage in the given flow
*
* @internal
* @returns login type
*/
private firstUncompletedStage;
}
export {};
//# sourceMappingURL=interactive-auth.d.ts.map
|