|
1 | 1 | // Copyright 2022 Gnuxie <Gnuxie@protonmail.com> |
2 | 2 | // Copyright 2022 The Matrix.org Foundation C.I.C. |
| 3 | +// SPDX-FileCopyrightText: 2026 Catalan Lover <catalanlover@protonmail.com> |
3 | 4 | // |
4 | 5 | // SPDX-License-Identifier: AFL-3.0 AND Apache-2.0 |
5 | 6 | // |
@@ -185,6 +186,7 @@ export class MjolnirAppService { |
185 | 186 | const serverName = config.homeserver.domain; |
186 | 187 | const mjolnirManager = await AppServiceDraupnirManager.makeDraupnirManager( |
187 | 188 | serverName, |
| 189 | + config.maxDraupnirsPerUser ?? 1, |
188 | 190 | dataStore, |
189 | 191 | bridge, |
190 | 192 | accessControl, |
@@ -263,60 +265,101 @@ export class MjolnirAppService { |
263 | 265 | log.info( |
264 | 266 | `${mxEvent.sender} has sent an invitation to the appservice bot ${this.bridge.botUserId}, attempting to provision them a draupnir` |
265 | 267 | ); |
266 | | - // Join the room and try to send the welcome flow |
| 268 | + const client = this.bridge.getBot().getClient(); |
267 | 269 | try { |
268 | | - await this.bridge.getBot().getClient().joinRoom(mxEvent.room_id); |
269 | | - await this.bridge |
270 | | - .getBot() |
271 | | - .getClient() |
272 | | - .sendText( |
| 270 | + // Join the room so we can notify the requester and then reject the invite. |
| 271 | + try { |
| 272 | + await client.joinRoom(mxEvent.room_id); |
| 273 | + } catch (e: unknown) { |
| 274 | + log.error( |
| 275 | + `Failed to join the room by ${mxEvent.sender} to process provisioning invite`, |
| 276 | + e |
| 277 | + ); |
| 278 | + return; |
| 279 | + } |
| 280 | + |
| 281 | + if (!this.config.allowSelfServiceProvisioning) { |
| 282 | + await client |
| 283 | + .sendText( |
| 284 | + mxEvent.room_id, |
| 285 | + "Self-service provisioning is disabled. Please ask an admin to provision a Draupnir for you." |
| 286 | + ) |
| 287 | + .catch((e: unknown) => { |
| 288 | + log.error( |
| 289 | + `Failed to notify ${mxEvent.sender} that self-service provisioning is disabled`, |
| 290 | + e |
| 291 | + ); |
| 292 | + }); |
| 293 | + return; |
| 294 | + } |
| 295 | + |
| 296 | + try { |
| 297 | + await client.sendText( |
273 | 298 | mxEvent.room_id, |
274 | 299 | "Your Draupnir is currently being provisioned. Please wait while we set up the rooms." |
275 | 300 | ); |
276 | | - } catch (e: unknown) { |
277 | | - log.error( |
278 | | - `Failed to join the room by ${mxEvent.sender} to display the welcome flow`, |
279 | | - e |
280 | | - ); |
281 | | - } |
282 | | - try { |
283 | | - const result = await this.draupnirManager.provisionNewDraupnir( |
284 | | - mxEvent.sender as StringUserID |
285 | | - ); |
286 | | - if (isError(result)) { |
| 301 | + } catch (e: unknown) { |
| 302 | + log.error( |
| 303 | + `Failed to send provisioning welcome flow to ${mxEvent.sender}; aborting provisioning`, |
| 304 | + e |
| 305 | + ); |
| 306 | + // We don´t want to continue with provisioning because we don´t have a working communications channel with the user. |
| 307 | + return; |
| 308 | + } |
| 309 | + // Ideallly we need to rework provisionNewDraupnir because its current state does not catch all expected errors. |
| 310 | + let provisioningFailed = false; |
| 311 | + try { |
| 312 | + const provisionResult = await this.draupnirManager.provisionNewDraupnir( |
| 313 | + mxEvent.sender as StringUserID |
| 314 | + ); |
| 315 | + if (isError(provisionResult)) { |
| 316 | + log.error( |
| 317 | + `Failed to provision a draupnir for ${mxEvent.sender} after they invited ${this.bridge.botUserId}`, |
| 318 | + provisionResult.error |
| 319 | + ); |
| 320 | + provisioningFailed = true; |
| 321 | + } |
| 322 | + } catch (e: unknown) { |
287 | 323 | log.error( |
288 | 324 | `Failed to provision a draupnir for ${mxEvent.sender} after they invited ${this.bridge.botUserId}`, |
289 | | - result.error |
| 325 | + e |
290 | 326 | ); |
| 327 | + provisioningFailed = true; |
| 328 | + } |
| 329 | + |
| 330 | + if (provisioningFailed) { |
| 331 | + try { |
| 332 | + await client.sendText( |
| 333 | + mxEvent.room_id, |
| 334 | + "Please make sure you are allowed to provision a bot. Otherwise please notify the admin. The provisioning request was rejected." |
| 335 | + ); |
| 336 | + } catch (e: unknown) { |
| 337 | + log.error( |
| 338 | + `Failed to send provisioning failure flow to ${mxEvent.sender}`, |
| 339 | + e |
| 340 | + ); |
| 341 | + } |
| 342 | + return; |
291 | 343 | } |
292 | | - // Send a notice that the invite must be accepted |
293 | | - await this.bridge |
294 | | - .getBot() |
295 | | - .getClient() |
296 | | - .sendText( |
| 344 | + // Send a notice that the invite must be accepted. |
| 345 | + try { |
| 346 | + await client.sendText( |
297 | 347 | mxEvent.room_id, |
298 | | - "Please accept the inviations to the newly provisioned rooms. These will be the home of your Draupnir Instance. This room will not be used in the future." |
| 348 | + "Please accept the invitations to the newly provisioned rooms. These will be the home of your Draupnir Instance. This room will not be used in the future." |
299 | 349 | ); |
300 | | - } catch (e: unknown) { |
301 | | - log.error( |
302 | | - `Failed to provision a draupnir for ${mxEvent.sender} after they invited ${this.bridge.botUserId}:`, |
303 | | - e |
304 | | - ); |
305 | | - // continue, we still want to reject this invitation. |
306 | | - // Send a notice that the provisioning failed |
307 | | - await this.bridge |
308 | | - .getBot() |
309 | | - .getClient() |
310 | | - .sendText( |
311 | | - mxEvent.room_id, |
312 | | - "Please make sure you are allowed to provision a bot. Otherwise please notify the admin. The provisioning request was rejected." |
| 350 | + } catch (e: unknown) { |
| 351 | + log.error( |
| 352 | + `Failed to send provisioning success flow to ${mxEvent.sender}`, |
| 353 | + e |
313 | 354 | ); |
314 | | - } |
315 | | - try { |
316 | | - // reject the invite to keep the room clean and make sure the invetee doesn't get confused and think this is their draupnir. |
317 | | - await this.bridge.getBot().getClient().leaveRoom(mxEvent.room_id); |
318 | | - } catch (e: unknown) { |
319 | | - log.warn("Unable to reject an invite to a room", e); |
| 355 | + } |
| 356 | + } finally { |
| 357 | + try { |
| 358 | + // Reject the invite to keep the room clean and make sure the invitee doesn't get confused and think this is their draupnir. |
| 359 | + await client.leaveRoom(mxEvent.room_id); |
| 360 | + } catch (e: unknown) { |
| 361 | + log.warn("Unable to reject an invite to a room", e); |
| 362 | + } |
320 | 363 | } |
321 | 364 | } |
322 | 365 |
|
|
0 commit comments