Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added endpoint to reset password #140

Merged
merged 25 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8b16ee6
feat : added getAccessToken function in utils to get the access token…
BichraiX Aug 14, 2024
3fceda6
fix : changed "token" to data in authenticate to prevent confusion wi…
BichraiX Aug 14, 2024
c011be3
fix : filled empty catch statements
BichraiX Aug 14, 2024
4d6c089
feat : added function that returns whether a user is an admin or not …
BichraiX Aug 14, 2024
de71e74
chore : prettier
BichraiX Aug 14, 2024
f3b7925
feat : added endpoint to change user's password
BichraiX Aug 14, 2024
aa54f44
chore : added spec link
BichraiX Aug 14, 2024
61311a6
fix : console to logger
BichraiX Aug 16, 2024
adeeaec
feat : added delete endpoint
BichraiX Aug 13, 2024
a47f4df
fix : await in response.json and added user name in error response
BichraiX Aug 13, 2024
1c10c89
fix : added promise.resolve in mock calls
BichraiX Aug 13, 2024
3154949
feat : added endpoint to change user's password
BichraiX Aug 14, 2024
9a69fbe
feat : added delete endpoint
BichraiX Aug 13, 2024
384ae30
feat: added sql requests in sqlite and PG for the user_directory_dear…
Mathixx Aug 14, 2024
ad7c756
fix: reorganized profiles and user_directory
Mathixx Aug 14, 2024
4e4e6f9
feat: added tests fro the search API, as well as for the added functi…
Mathixx Aug 15, 2024
cda3302
feat: finish doc for the user_directory API
Mathixx Aug 15, 2024
8d2622d
fix: completed doc
Mathixx Aug 15, 2024
ce95968
feat : added endpoint to change user's password
BichraiX Aug 14, 2024
2928c07
feat : added delete endpoint
BichraiX Aug 13, 2024
c7d8a66
feat : added endpoint to change user's password
BichraiX Aug 14, 2024
f3e9e2e
fix : merge issue
BichraiX Aug 16, 2024
104f811
fix : merge issues
BichraiX Aug 16, 2024
bd72ad9
chore : prettier
BichraiX Aug 16, 2024
abcb155
Merge branch 'full-id-service' into client-server-password-reset
BichraiX Aug 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,6 @@
"is_password_login_enabled": true,
"is_sso_login_enabled": true,
"is_msisdn_login_enabled": true,
"registration_required_3pid": []
"registration_required_3pid": [],
"capabilities": {}
}
69 changes: 62 additions & 7 deletions packages/matrix-client-server/src/account/3pid/3pid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,41 @@ describe('Use configuration file', () => {
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_THREEPID_IN_USE')
})

it('should refuse to add a 3pid if the user is not an admin and the server does not allow it', async () => {
clientServer.conf.capabilities.enable_3pid_changes = false
const response1 = await request(app)
.post('/_matrix/client/v3/account/3pid/add')
.set('Accept', 'application/json')
.set('Authorization', `Bearer ${validToken}`)
.send({
sid: 'sid',
client_secret: 'my'
})
expect(response1.statusCode).toBe(401)
session = response1.body.session
const response = await request(app)
.post('/_matrix/client/v3/account/3pid/add')
.set('Accept', 'application/json')
.set('Authorization', `Bearer ${validToken}`)
.send({
sid,
client_secret: 'mysecret',
auth: {
type: 'm.login.password',
session,
password:
'$2a$10$zQJv3V3Kjw7Jq7Ww1X7z5e1QXsVd1m3JdV9vG6t8Jv7jQz4Z5J1QK',
identifier: { type: 'm.id.user', user: '@testuser:example.com' }
}
})
expect(response.statusCode).toBe(403)
expect(response.body).toHaveProperty('errcode', 'M_FORBIDDEN')
expect(response.body).toHaveProperty(
'error',
'Cannot add 3pid as it is not allowed by server'
)
delete clientServer.conf.capabilities.enable_3pid_changes
})
// Used to work but not anymore since we only check UI Auth with m.login.password or m.login.sso
// it('should refuse adding a userId that is not of the right format', async () => {
// const response = await request(app)
Expand Down Expand Up @@ -494,7 +528,7 @@ describe('Use configuration file', () => {
'This validation session has not yet been completed'
)
})
it('should return a 500 error if the medium is incorrect', async () => {
it('should return a 400 error if the medium is incorrect', async () => {
const mockResolveResponse = Promise.resolve({
ok: true,
status: 200,
Expand Down Expand Up @@ -539,14 +573,14 @@ describe('Use configuration file', () => {
sid: 'mysid'
})

expect(response.statusCode).toBe(500)
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty(
'error',
'Medium must be one of "email" or "msisdn"'
)
})
it('should return a 500 error if the email is incorrect', async () => {
it('should return a 400 error if the email is incorrect', async () => {
const mockResolveResponse = Promise.resolve({
ok: true,
status: 200,
Expand Down Expand Up @@ -591,11 +625,11 @@ describe('Use configuration file', () => {
sid: 'mysid'
})

expect(response.statusCode).toBe(500)
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty('error', 'Invalid email')
})
it('should return a 500 error if the phone number is incorrect', async () => {
it('should return a 400 error if the phone number is incorrect', async () => {
const mockResolveResponse = Promise.resolve({
ok: true,
status: 200,
Expand Down Expand Up @@ -640,10 +674,31 @@ describe('Use configuration file', () => {
sid: 'mysid'
})

expect(response.statusCode).toBe(500)
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty('error', 'Invalid phone number')
})
it('should return 403 if the user is not an admin and the server does not allow it', async () => {
clientServer.conf.capabilities.enable_3pid_changes = false
const response = await request(app)
.post('/_matrix/client/v3/account/3pid/bind')
.set('Authorization', `Bearer ${validToken}`)
.set('Accept', 'application/json')
.send({
client_secret: 'mysecret',
id_access_token: 'myaccesstoken',
id_server: 'matrix.example.com',
sid: 'mysid'
})

expect(response.statusCode).toBe(403)
expect(response.body).toHaveProperty('errcode', 'M_FORBIDDEN')
expect(response.body).toHaveProperty(
'error',
'Cannot bind 3pid to user account as it is not allowed by server'
)
delete clientServer.conf.capabilities.enable_3pid_changes
})
})
})
})
218 changes: 131 additions & 87 deletions packages/matrix-client-server/src/account/3pid/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { type AuthenticationData } from '../../types'
import type MatrixClientServer from '../..'
import { validateUserWithUIAuthentication } from '../../utils/userInteractiveAuthentication'
import { isAdmin } from '../../utils/utils'

interface RequestBody {
auth: AuthenticationData
Expand Down Expand Up @@ -39,94 +40,137 @@ const add = (clientServer: MatrixClientServer): expressAppHandler => {
'add a 3pid to a user account',
data,
(obj, userId) => {
validateParameters(res, schema, obj, clientServer.logger, (obj) => {
if (!isClientSecretValid((obj as RequestBody).client_secret)) {
send(
res,
400,
errMsg('invalidParam', 'Invalid client_secret'),
clientServer.logger
)
return
}
if (!isSidValid((obj as RequestBody).sid)) {
send(
res,
400,
errMsg('invalidParam', 'Invalid session ID'),
clientServer.logger
)
return
}
const body = obj as RequestBody
clientServer.matrixDb
.get(
'threepid_validation_session',
['address', 'medium', 'validated_at'],
{
// Get the address from the validation session. This API has to be called after /requestToken, else it will send error 400
client_secret: body.client_secret,
session_id: body.sid
}
)
.then((sessionRows) => {
if (sessionRows.length === 0) {
send(res, 400, errMsg('noValidSession'), clientServer.logger)
return
}
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
if (!sessionRows[0].validated_at) {
send(
res,
400,
errMsg('sessionNotValidated'),
clientServer.logger
)
return
}
clientServer.matrixDb
.get('user_threepids', ['user_id'], {
address: sessionRows[0].address
})
.then((rows) => {
if (rows.length > 0) {
send(
res,
400,
errMsg('threepidInUse'),
clientServer.logger
validateParameters(
res,
schema,
obj,
clientServer.logger,
// eslint-disable-next-line @typescript-eslint/no-misused-promises
async (obj) => {
if (!isClientSecretValid((obj as RequestBody).client_secret)) {
send(
res,
400,
errMsg('invalidParam', 'Invalid client_secret'),
clientServer.logger
)
return
}
if (!isSidValid((obj as RequestBody).sid)) {
send(
res,
400,
errMsg('invalidParam', 'Invalid session ID'),
clientServer.logger
)
return
}
const body = obj as RequestBody
const byAdmin = await isAdmin(clientServer, userId as string)
const allowed =
clientServer.conf.capabilities.enable_3pid_changes ?? true
if (!byAdmin && !allowed) {
send(
res,
403,
errMsg(
'forbidden',
'Cannot add 3pid as it is not allowed by server'
),
clientServer.logger
)
return
}
clientServer.matrixDb
.get(
'threepid_validation_session',
['address', 'medium', 'validated_at'],
{
// Get the address from the validation session. This API has to be called after /requestToken, else it will send error 400
client_secret: body.client_secret,
session_id: body.sid
}
)
.then((sessionRows) => {
if (sessionRows.length === 0) {
send(
res,
400,
errMsg('noValidSession'),
clientServer.logger
)
return
}
if (
sessionRows[0].validated_at === null ||
sessionRows[0].validated_at === undefined
) {
send(
res,
400,
errMsg('sessionNotValidated'),
clientServer.logger
)
return
}
clientServer.matrixDb
.get('user_threepids', ['user_id'], {
address: sessionRows[0].address
})
.then((rows) => {
if (rows.length > 0) {
send(
res,
400,
errMsg('threepidInUse'),
clientServer.logger
)
} else {
clientServer.matrixDb
.insert('user_threepids', {
user_id: userId as string,
address: sessionRows[0].address as string,
medium: sessionRows[0].medium as string,
validated_at: sessionRows[0].validated_at as number,
added_at: epoch()
})
.then(() => {
send(res, 200, {}, clientServer.logger)
})
.catch((e) => {
// istanbul ignore next
clientServer.logger.error(
'Error while inserting user_threepids'
)
// istanbul ignore next
send(
res,
400,
errMsg('unknown', e),
clientServer.logger
)
})
}
})
.catch((e) => {
// istanbul ignore next
clientServer.logger.error(
'Error while getting user_threepids'
)
} else {
clientServer.matrixDb
.insert('user_threepids', {
user_id: userId as string,
address: sessionRows[0].address as string,
medium: sessionRows[0].medium as string,
validated_at: sessionRows[0].validated_at as number,
added_at: epoch()
})
.then(() => {
send(res, 200, {}, clientServer.logger)
})
.catch((e) => {
// istanbul ignore next
clientServer.logger.error(
'Error while inserting user_threepids'
)
// istanbul ignore next
send(
res,
400,
errMsg('unknown', e),
clientServer.logger
)
})
}
})
.catch((e) => {})
})
.catch((e) => {})
})
// istanbul ignore next
send(res, 500, errMsg('unknown', e), clientServer.logger)
})
})
.catch((e) => {
// istanbul ignore next
clientServer.logger.error(
'Error while getting threepid_validation_session'
)
// istanbul ignore next
send(res, 500, errMsg('unknown', e), clientServer.logger)
})
}
)
}
)
})
Expand Down
Loading
Loading