|
7 | 7 | validateParameters,
|
8 | 8 | type expressAppHandler
|
9 | 9 | } from '@twake/utils'
|
| 10 | +import { buildUrl, getServerNameFromMatrixId } from '../utils' |
| 11 | +import type { onBindRequestPayload } from '../types' |
10 | 12 |
|
11 | 13 | const clientSecretRe = /^[0-9a-zA-Z.=_-]{6,255}$/
|
12 | 14 | const mxidRe = /^@[0-9a-zA-Z._=-]+:[0-9a-zA-Z.-]+$/
|
@@ -78,7 +80,18 @@ const bind = <T extends string = never>(
|
78 | 80 | return
|
79 | 81 | }
|
80 | 82 |
|
81 |
| - // TODO : hook for any pending invite and call the onbind api : https://spec.matrix.org/v1.11/client-server-api/#room-aliases |
| 83 | + _onBind( |
| 84 | + idServer, |
| 85 | + (obj as RequestTokenArgs).mxid, |
| 86 | + rows[0].address as string, |
| 87 | + rows[0].medium as string |
| 88 | + ) |
| 89 | + .then(() => { |
| 90 | + idServer.logger.info(`Finished server onbind for ${mxid}`) |
| 91 | + }) |
| 92 | + .catch((err) => { |
| 93 | + idServer.logger.error('Error calling server onbind', err) |
| 94 | + }) |
82 | 95 |
|
83 | 96 | idServer.db
|
84 | 97 | .get('keys', ['data'], { name: 'pepper' })
|
@@ -152,4 +165,59 @@ const bind = <T extends string = never>(
|
152 | 165 | }
|
153 | 166 | }
|
154 | 167 |
|
| 168 | +/** |
| 169 | + * Calls the Matrix server onbind hook |
| 170 | + * @summary spec: https://spec.matrix.org/v1.13/server-server-api/#third-party-invites |
| 171 | + * |
| 172 | + * @param {MatrixIdentityServer} idServer |
| 173 | + * @param {string} mxid |
| 174 | + * @param {string} address |
| 175 | + * @param {string} medium |
| 176 | + */ |
| 177 | +const _onBind = async <T extends string = never>( |
| 178 | + idServer: MatrixIdentityServer<T>, |
| 179 | + mxid: string, |
| 180 | + address: string, |
| 181 | + medium: string |
| 182 | +): Promise<void> => { |
| 183 | + try { |
| 184 | + const server = getServerNameFromMatrixId(mxid) |
| 185 | + const invitationTokens = await idServer.db.listInvitationTokens(address) |
| 186 | + |
| 187 | + if (!invitationTokens || !invitationTokens.length) { |
| 188 | + idServer.logger.info(`No pending invitations found for ${address}`) |
| 189 | + console.info(`No pending invitations found for ${address}`) |
| 190 | + |
| 191 | + return |
| 192 | + } |
| 193 | + |
| 194 | + const invites = invitationTokens.map(({ data }) => data) |
| 195 | + |
| 196 | + const response = await fetch( |
| 197 | + buildUrl(server, `/_matrix/federation/v1/3pid/onbind`), |
| 198 | + { |
| 199 | + method: 'POST', |
| 200 | + headers: { |
| 201 | + 'Content-Type': 'application/json' |
| 202 | + }, |
| 203 | + body: JSON.stringify({ |
| 204 | + mxid, |
| 205 | + address, |
| 206 | + medium, |
| 207 | + invites |
| 208 | + } satisfies onBindRequestPayload) |
| 209 | + } |
| 210 | + ) |
| 211 | + |
| 212 | + if (response.status !== 200) { |
| 213 | + throw new Error( |
| 214 | + `Failed to call onbind hook, status code: ${response.status}` |
| 215 | + ) |
| 216 | + } |
| 217 | + } catch (error) { |
| 218 | + console.error(`Failed to call onbind hook`, { error }) |
| 219 | + idServer.logger.error('Error calling onbind hook', error) |
| 220 | + } |
| 221 | +} |
| 222 | + |
155 | 223 | export default bind
|
0 commit comments