-
Notifications
You must be signed in to change notification settings - Fork 10k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: adds verification when inviting external matrixIds (#28096)
- Loading branch information
Showing
19 changed files
with
393 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
--- | ||
'@rocket.chat/core-services': minor | ||
'@rocket.chat/rest-typings': minor | ||
'@rocket.chat/meteor': minor | ||
--- | ||
|
||
New AddUser workflow for Federated Rooms |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { Federation, FederationEE } from '@rocket.chat/core-services'; | ||
import { isFederationVerifyMatrixIdProps } from '@rocket.chat/rest-typings'; | ||
|
||
import { isEnterprise } from '../../../../ee/app/license/server'; | ||
import { API } from '../api'; | ||
|
||
API.v1.addRoute( | ||
'federation/matrixIds.verify', | ||
{ | ||
authRequired: true, | ||
validateParams: isFederationVerifyMatrixIdProps, | ||
}, | ||
{ | ||
async get() { | ||
const { matrixIds } = this.queryParams; | ||
|
||
const federationService = isEnterprise() ? FederationEE : Federation; | ||
|
||
const results = await federationService.verifyMatrixIds(matrixIds); | ||
|
||
return API.v1.success({ results: Object.fromEntries(results) }); | ||
}, | ||
}, | ||
); |
83 changes: 83 additions & 0 deletions
83
...ient/views/room/contextualBar/RoomMembers/AddUsers/AddMatrixUsers/AddMatrixUsersModal.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { Modal, Button, Box, Icon } from '@rocket.chat/fuselage'; | ||
import { useToastMessageDispatch, useTranslation } from '@rocket.chat/ui-contexts'; | ||
import type { ComponentProps, ReactElement } from 'react'; | ||
import React from 'react'; | ||
import { useForm } from 'react-hook-form'; | ||
|
||
type AddMatrixUsersModalProps = { | ||
matrixIdVerifiedStatus: Map<string, string>; | ||
completeUserList: string[]; | ||
onClose: () => void; | ||
onSave: (args_0: any) => Promise<void>; | ||
}; | ||
|
||
type FormValues = { | ||
usersToInvite: string[]; | ||
}; | ||
|
||
const verificationStatusAsIcon = (verificationStatus: string) => { | ||
if (verificationStatus === 'VERIFIED') { | ||
return 'circle-check'; | ||
} | ||
|
||
if (verificationStatus === 'UNVERIFIED') { | ||
return 'circle-cross'; | ||
} | ||
|
||
if (verificationStatus === 'UNABLE_TO_VERIFY') { | ||
return 'circle-exclamation'; | ||
} | ||
}; | ||
|
||
const AddMatrixUsersModal = ({ onClose, matrixIdVerifiedStatus, onSave, completeUserList }: AddMatrixUsersModalProps): ReactElement => { | ||
const dispatchToastMessage = useToastMessageDispatch(); | ||
const usersToInvite = completeUserList.filter( | ||
(user) => !(matrixIdVerifiedStatus.has(user) && matrixIdVerifiedStatus.get(user) === 'UNVERIFIED'), | ||
); | ||
|
||
const { handleSubmit } = useForm<FormValues>({ | ||
defaultValues: { | ||
usersToInvite, | ||
}, | ||
}); | ||
|
||
const onSubmit = (data: FormValues) => { | ||
onSave({ users: data.usersToInvite }) | ||
.then(onClose) | ||
.catch((error) => dispatchToastMessage({ type: 'error', message: error as Error })); | ||
}; | ||
|
||
const t = useTranslation(); | ||
|
||
return ( | ||
<Modal> | ||
<Modal.Header> | ||
<Modal.HeaderText> | ||
<Modal.Title>Sending Invitations</Modal.Title> | ||
</Modal.HeaderText> | ||
<Modal.Close title={t('Close')} onClick={onClose} /> | ||
</Modal.Header> | ||
<Modal.Content> | ||
<Box> | ||
<Box is='ul'> | ||
{[...matrixIdVerifiedStatus.entries()].map(([_matrixId, _verificationStatus]) => ( | ||
<li key={_matrixId}> | ||
{_matrixId}: <Icon name={verificationStatusAsIcon(_verificationStatus) as ComponentProps<typeof Icon>['name']} size='x20' /> | ||
</li> | ||
))} | ||
</Box> | ||
</Box> | ||
</Modal.Content> | ||
<Modal.Footer justifyContent='center'> | ||
<Modal.FooterControllers> | ||
<Button onClick={onClose}>{t('Cancel')}</Button> | ||
<Button primary onClick={handleSubmit(onSubmit)} disabled={!(usersToInvite.length > 0)}> | ||
{t('Yes_continue')} | ||
</Button> | ||
</Modal.FooterControllers> | ||
</Modal.Footer> | ||
</Modal> | ||
); | ||
}; | ||
|
||
export default AddMatrixUsersModal; |
39 changes: 39 additions & 0 deletions
39
...client/views/room/contextualBar/RoomMembers/AddUsers/AddMatrixUsers/useAddMatrixUsers.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { useMutableCallback } from '@rocket.chat/fuselage-hooks'; | ||
import { useSetModal, useToastMessageDispatch, useEndpoint } from '@rocket.chat/ui-contexts'; | ||
import { useMutation } from '@tanstack/react-query'; | ||
import React from 'react'; | ||
|
||
import AddMatrixUsersModal from './AddMatrixUsersModal'; | ||
|
||
export type useAddMatrixUsersProps = { | ||
handleSave: (args_0: any) => Promise<void>; | ||
users: string[]; | ||
}; | ||
|
||
export const useAddMatrixUsers = () => { | ||
const setModal = useSetModal(); | ||
const dispatchToastMessage = useToastMessageDispatch(); | ||
const handleClose = useMutableCallback(() => setModal(null)); | ||
const dispatchVerifyEndpoint = useEndpoint('GET', '/v1/federation/matrixIds.verify'); | ||
|
||
return useMutation(async ({ users, handleSave }: useAddMatrixUsersProps) => { | ||
try { | ||
let matrixIdVerificationMap = new Map(); | ||
const matrixIds = users.filter((user) => user.startsWith('@')); | ||
const matrixIdsVerificationResponse = await dispatchVerifyEndpoint({ matrixIds }); | ||
const { results: matrixIdsVerificationResults } = matrixIdsVerificationResponse; | ||
matrixIdVerificationMap = new Map(Object.entries(matrixIdsVerificationResults)); | ||
|
||
setModal( | ||
<AddMatrixUsersModal | ||
completeUserList={users} | ||
onClose={handleClose} | ||
onSave={handleSave} | ||
matrixIdVerifiedStatus={matrixIdVerificationMap as Map<string, string>} | ||
/>, | ||
); | ||
} catch (error) { | ||
dispatchToastMessage({ type: 'error', message: error as Error }); | ||
} | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
apps/meteor/server/services/federation/infrastructure/matrix/helpers/HtttpStatusCodes.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
export const enum HttpStatusCodes { | ||
CONTINUE = 100, | ||
SWITCHING_PROTOCOLS = 101, | ||
PROCESSING = 102, | ||
OK = 200, | ||
CREATED = 201, | ||
ACCEPTED = 202, | ||
NON_AUTHORITATIVE_INFORMATION = 203, | ||
NO_CONTENT = 204, | ||
RESET_CONTENT = 205, | ||
PARTIAL_CONTENT = 206, | ||
MULTI_STATUS = 207, | ||
MULTIPLE_CHOICES = 300, | ||
MOVED_PERMANENTLY = 301, | ||
MOVED_TEMPORARILY = 302, | ||
SEE_OTHER = 303, | ||
NOT_MODIFIED = 304, | ||
USE_PROXY = 305, | ||
TEMPORARY_REDIRECT = 307, | ||
PERMANENT_REDIRECT = 308, | ||
BAD_REQUEST = 400, | ||
UNAUTHORIZED = 401, | ||
PAYMENT_REQUIRED = 402, | ||
FORBIDDEN = 403, | ||
NOT_FOUND = 404, | ||
METHOD_NOT_ALLOWED = 405, | ||
NOT_ACCEPTABLE = 406, | ||
PROXY_AUTHENTICATION_REQUIRED = 407, | ||
REQUEST_TIMEOUT = 408, | ||
CONFLICT = 409, | ||
GONE = 410, | ||
LENGTH_REQUIRED = 411, | ||
PRECONDITION_FAILED = 412, | ||
REQUEST_TOO_LONG = 413, | ||
REQUEST_URI_TOO_LONG = 414, | ||
UNSUPPORTED_MEDIA_TYPE = 415, | ||
REQUESTED_RANGE_NOT_SATISFIABLE = 416, | ||
EXPECTATION_FAILED = 417, | ||
IM_A_TEAPOT = 418, | ||
INSUFFICIENT_SPACE_ON_RESOURCE = 419, | ||
METHOD_FAILURE = 420, | ||
MISDIRECTED_REQUEST = 421, | ||
UNPROCESSABLE_ENTITY = 422, | ||
LOCKED = 423, | ||
FAILED_DEPENDENCY = 424, | ||
PRECONDITION_REQUIRED = 428, | ||
TOO_MANY_REQUESTS = 429, | ||
REQUEST_HEADER_FIELDS_TOO_LARGE = 431, | ||
UNAVAILABLE_FOR_LEGAL_REASONS = 451, | ||
INTERNAL_SERVER_ERROR = 500, | ||
NOT_IMPLEMENTED = 501, | ||
BAD_GATEWAY = 502, | ||
SERVICE_UNAVAILABLE = 503, | ||
GATEWAY_TIMEOUT = 504, | ||
HTTP_VERSION_NOT_SUPPORTED = 505, | ||
INSUFFICIENT_STORAGE = 507, | ||
NETWORK_AUTHENTICATION_REQUIRED = 511, | ||
} |
25 changes: 25 additions & 0 deletions
25
apps/meteor/server/services/federation/infrastructure/matrix/helpers/MatrixIdStringTools.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
export const removeExternalSpecificCharsFromExternalIdentifier = (matrixId = ''): string => { | ||
return matrixId.replace('@', '').replace('!', '').replace('#', ''); | ||
}; | ||
|
||
export const formatExternalUserIdToInternalUsernameFormat = (matrixId = ''): string => { | ||
return matrixId.split(':')[0]?.replace('@', ''); | ||
}; | ||
|
||
export const formatExternalAliasIdToInternalFormat = (alias = ''): string => { | ||
return alias.split(':')[0]?.replace('#', ''); | ||
}; | ||
|
||
export const isAnExternalIdentifierFormat = (identifier: string): boolean => identifier.includes(':'); | ||
|
||
export const isAnExternalUserIdFormat = (userId: string): boolean => isAnExternalIdentifierFormat(userId) && userId.includes('@'); | ||
|
||
export const extractServerNameFromExternalIdentifier = (identifier = ''): string => { | ||
const splitted = identifier.split(':'); | ||
|
||
return splitted.length > 1 ? splitted[1] : ''; | ||
}; | ||
|
||
export const extractUserIdAndHomeserverFromMatrixId = (matrixId = ''): string[] => { | ||
return matrixId.replace('@', '').split(':'); | ||
}; |
Oops, something went wrong.