Skip to content

Commit

Permalink
feat : added function to get stream_ids by batches. Added device mess…
Browse files Browse the repository at this point in the history
…ages deletion by batches of 10, finished delete_devices endpoint
  • Loading branch information
BichraiX committed Aug 22, 2024
1 parent cf00e05 commit 34e91ac
Show file tree
Hide file tree
Showing 20 changed files with 817 additions and 131 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ const matrixDbQueries = [
'CREATE TABLE IF NOT EXISTS e2e_device_keys_json ( user_id TEXT NOT NULL, device_id TEXT NOT NULL, ts_added_ms BIGINT NOT NULL, key_json TEXT NOT NULL, CONSTRAINT e2e_device_keys_json_uniqueness UNIQUE (user_id, device_id) )',
'CREATE TABLE IF NOT EXISTS e2e_one_time_keys_json ( user_id TEXT NOT NULL, device_id TEXT NOT NULL, algorithm TEXT NOT NULL, key_id TEXT NOT NULL, ts_added_ms BIGINT NOT NULL, key_json TEXT NOT NULL, CONSTRAINT e2e_one_time_keys_json_uniqueness UNIQUE (user_id, device_id, algorithm, key_id) )',
'CREATE TABLE IF NOT EXISTS e2e_fallback_keys_json (user_id TEXT NOT NULL, device_id TEXT NOT NULL, algorithm TEXT NOT NULL, key_id TEXT NOT NULL, key_json TEXT NOT NULL, used BOOLEAN NOT NULL DEFAULT FALSE, CONSTRAINT e2e_fallback_keys_json_uniqueness UNIQUE (user_id, device_id, algorithm))',
'CREATE TABLE dehydrated_devices(user_id TEXT NOT NULL PRIMARY KEY,device_id TEXT NOT NULL,device_data TEXT NOT NULL)'
'CREATE TABLE dehydrated_devices(user_id TEXT NOT NULL PRIMARY KEY,device_id TEXT NOT NULL,device_data TEXT NOT NULL)',
'CREATE TABLE device_inbox ( user_id TEXT NOT NULL, device_id TEXT NOT NULL, stream_id BIGINT NOT NULL, message_json TEXT NOT NULL , instance_name TEXT)'
]

// eslint-disable-next-line @typescript-eslint/promise-function-async
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export let validToken: string
export let validToken1: string
export let validToken2: string
export let validToken3: string
export let validToken4 : string
export let validRefreshToken1: string
export let validRefreshToken2: string
export let validRefreshToken3: string
Expand All @@ -18,6 +19,7 @@ export async function setupTokens(
validToken1 = randomString(64)
validToken2 = randomString(64)
validToken3 = randomString(64)
validToken4 = randomString(64)
const validRefreshTokenId1 = randomString(64)
const validRefreshTokenId2 = randomString(64)
const validRefreshTokenId3 = randomString(64)
Expand Down Expand Up @@ -141,7 +143,12 @@ export async function setupTokens(
validated_at: epoch(),
added_at: epoch()
})

await clientServer.matrixDb.insert('access_tokens', {
id: randomString(64),
user_id: '@validated:example.com',
device_id: 'thirddevice',
token: validToken4
})
await clientServer.matrixDb.insert('access_tokens', {
id: randomString(64),
user_id: '@thirduser:example.com',
Expand Down
83 changes: 50 additions & 33 deletions packages/matrix-client-server/src/account/3pid/3pid.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ describe('Use configuration file', () => {
.set('Authorization', `Bearer wrongUserAccessToken`)
.send({
sid: 'sid',
client_secret: 'cs'
client_secret: 'clientsecret'
})
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
Expand All @@ -140,7 +140,7 @@ describe('Use configuration file', () => {
.set('Authorization', `Bearer ${validToken2}`)
.send({
sid: 'sid',
client_secret: 'cs'
client_secret: 'clientsecret'
})
expect(response.statusCode).toBe(401)
session = response.body.session
Expand All @@ -150,7 +150,7 @@ describe('Use configuration file', () => {
.set('Authorization', `Bearer ${validToken2}`)
.send({
sid: 'sid',
client_secret: 'cs',
client_secret: 'clientsecret',
auth: {
type: 'm.login.password',
session,
Expand All @@ -165,23 +165,13 @@ describe('Use configuration file', () => {
expect(response1.body).toHaveProperty('errcode', 'M_FORBIDDEN')
expect(response1.body).toHaveProperty(
'error',
'The user does not have a password registered'
'The user does not have a password registered or the provided password is wrong.'
)
})
})
let sid: string
let token: string
it('should refuse an invalid secret', async () => {
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')
Expand All @@ -191,7 +181,7 @@ describe('Use configuration file', () => {
client_secret: 'my',
auth: {
type: 'm.login.password',
session,
session: 'session',
password:
'$2a$10$zQJv3V3Kjw7Jq7Ww1X7z5e1QXsVd1m3JdV9vG6t8Jv7jQz4Z5J1QK',
identifier: { type: 'm.id.user', user: '@testuser:example.com' }
Expand All @@ -202,16 +192,6 @@ describe('Use configuration file', () => {
expect(response.body).toHaveProperty('error', 'Invalid client_secret')
})
it('should refuse an invalid session ID', async () => {
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')
Expand All @@ -221,7 +201,7 @@ describe('Use configuration file', () => {
client_secret: 'mysecret',
auth: {
type: 'm.login.password',
session,
session: 'session',
password:
'$2a$10$zQJv3V3Kjw7Jq7Ww1X7z5e1QXsVd1m3JdV9vG6t8Jv7jQz4Z5J1QK',
identifier: { type: 'm.id.user', user: '@testuser:example.com' }
Expand All @@ -231,16 +211,33 @@ describe('Use configuration file', () => {
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty('error', 'Invalid session ID')
})
it('should return 400 for a wrong combination of client secret and session ID', async () => {
const response1 = await request(app)
it('should refuse an invalid auth', async () => {
const response = await request(app)
.post('/_matrix/client/v3/account/3pid/add')
.set('Accept', 'application/json')
.set('Authorization', `Bearer ${validToken}`)
.send({
sid: 'sid',
client_secret: 'my'
client_secret: 'mysecret',
auth: {
type: 'invalidtype'
}
})
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty(
'error',
'Invalid authentication data'
)
})
it('should return 400 for a wrong combination of client secret and session ID', async () => {
const response1 = await request(app)
.post('/_matrix/client/v3/account/3pid/add')
.set('Accept', 'application/json')
.set('Authorization', `Bearer ${validToken}`)
.send({})
expect(response1.statusCode).toBe(401)
expect(response1.body).toHaveProperty('session')
session = response1.body.session
const response = await request(app)
.post('/_matrix/client/v3/account/3pid/add')
Expand Down Expand Up @@ -283,8 +280,9 @@ describe('Use configuration file', () => {
.set('Authorization', `Bearer ${validToken}`)
.send({
sid: 'sid',
client_secret: 'my'
client_secret: 'mysecret'
})
console.log('response : ', response1.body)
expect(response1.statusCode).toBe(401)
session = response1.body.session
const response = await request(app)
Expand Down Expand Up @@ -324,7 +322,7 @@ describe('Use configuration file', () => {
.set('Authorization', `Bearer ${validToken}`)
.send({
sid: 'sid',
client_secret: 'my'
client_secret: 'mysecret'
})
expect(response1.statusCode).toBe(401)
session = response1.body.session
Expand Down Expand Up @@ -352,7 +350,7 @@ describe('Use configuration file', () => {
.set('Authorization', `Bearer ${validToken}`)
.send({
sid: 'sid',
client_secret: 'my'
client_secret: 'mysecret'
})
expect(response1.statusCode).toBe(401)
session = response1.body.session
Expand Down Expand Up @@ -382,7 +380,7 @@ describe('Use configuration file', () => {
.set('Authorization', `Bearer ${validToken}`)
.send({
sid: 'sid',
client_secret: 'my'
client_secret: 'mysecret'
})
expect(response1.statusCode).toBe(401)
session = response1.body.session
Expand Down Expand Up @@ -431,6 +429,25 @@ describe('Use configuration file', () => {
// })
})
describe('/_matrix/client/v3/account/3pid/delete', () => {
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/delete')
.set('Authorization', `Bearer ${validToken}`)
.set('Accept', 'application/json')
.send({
medium: 'email',
address: '[email protected]'
})

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
})
it('should refuse an invalid medium', async () => {
const response = await request(app)
.post('/_matrix/client/v3/account/3pid/delete')
Expand Down
2 changes: 1 addition & 1 deletion packages/matrix-client-server/src/account/3pid/delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const delete3pid = async (
}
)
if (rows.length === 0) {
throw Error(`No id_server found corresponding to user ${userId}`)
return { success: false, status: 400 }
} else {
idServer = rows[0].id_server as string
}
Expand Down
43 changes: 42 additions & 1 deletion packages/matrix-client-server/src/account/account.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,47 @@ describe('Use configuration file', () => {
)
clientServer.conf.capabilities.enable_set_avatar_url = true
})
it('should refuse an invalid auth', async () => {
const response = await request(app)
.post('/_matrix/client/v3/account/deactivate')
.set('Authorization', `Bearer ${validToken}`)
.set('Accept', 'application/json')
.send({
auth: {
type: 'm.login.password',
session: 'session',
password: 'wrongpassword',
identifier: { type: 'wrongtype', user: '@testuser:example.com' }
}
})
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty('error', 'Invalid auth')
})
it('should refuse an invalid id_server', async () => {
const response = await request(app)
.post('/_matrix/client/v3/account/deactivate')
.set('Authorization', `Bearer ${validToken}`)
.set('Accept', 'application/json')
.send({
id_server: 42
})
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty('error', 'Invalid id_server')
})
it('should refuse an invalid erase', async () => {
const response = await request(app)
.post('/_matrix/client/v3/account/deactivate')
.set('Authorization', `Bearer ${validToken}`)
.set('Accept', 'application/json')
.send({
erase: 'true'
})
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty('error', 'Invalid erase')
})
it('should deactivate a user account who authenticated with a token', async () => {
const response1 = await request(app)
.post('/_matrix/client/v3/account/deactivate')
Expand Down Expand Up @@ -504,7 +545,7 @@ describe('Use configuration file', () => {
expect(response.body).toHaveProperty('errcode', 'M_FORBIDDEN')
expect(response.body).toHaveProperty(
'error',
'The user does not have a password registered'
'The user does not have a password registered or the provided password is wrong.'
) // Error from UI Authentication since the password was deleted upon deactivation of the account
})
it('should send a no-support response if the identity server did not unbind the 3pid association', async () => {
Expand Down
28 changes: 20 additions & 8 deletions packages/matrix-client-server/src/account/deactivate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -500,24 +500,36 @@ const deactivate = (clientServer: MatrixClientServer): expressAppHandler => {
body.auth !== undefined &&
!verifyAuthenticationData(body.auth)
) {
clientServer.logger.error('Invalid auth')
send(res, 400, errMsg('invalidParam'), clientServer.logger)
send(
res,
400,
errMsg('invalidParam', 'Invalid auth'),
clientServer.logger
)
return
} else if (
body.id_server !== null ||
body.id_server !== undefined ||
body.id_server !== null &&
body.id_server !== undefined &&
!verifyString(body.id_server)
) {
clientServer.logger.error('Invalid id_server')
send(res, 400, errMsg('invalidParam'), clientServer.logger)
send(
res,
400,
errMsg('invalidParam', 'Invalid id_server'),
clientServer.logger
)
return
} else if (
body.erase !== null &&
body.erase !== undefined &&
!verifyBoolean(body.erase)
) {
clientServer.logger.error('Invalid erase')
send(res, 400, errMsg('invalidParam'), clientServer.logger)
send(
res,
400,
errMsg('invalidParam', 'Invalid erase'),
clientServer.logger
)
return
}
const token = getAccessToken(req)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ const passwordReset = (clientServer: MatrixClientServer): expressAppHandler => {
send(
res,
400,
errMsg('invalidParam', 'Invalid authentication data'),
errMsg('invalidParam', 'Invalid auth'),
clientServer.logger
)
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,42 @@ describe('Use configuration file', () => {
})
describe('/_matrix/client/v3/account/password', () => {
let session: string
it('should refuse an invalid logout_devices', async () => {
const response = await request(app)
.post('/_matrix/client/v3/account/password')
.set('Accept', 'application/json')
.set('Authorization', `Bearer ${validToken}`)
.send({
logout_devices: 'true'
})
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty('error', 'Invalid logout_devices')
})
it('should refuse an invalid new_password', async () => {
const response = await request(app)
.post('/_matrix/client/v3/account/password')
.set('Accept', 'application/json')
.set('Authorization', `Bearer ${validToken}`)
.send({
new_password: 55
})
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty('error', 'Invalid new_password')
})
it('should refuse an invalid auth', async () => {
const response = await request(app)
.post('/_matrix/client/v3/account/password')
.set('Accept', 'application/json')
.set('Authorization', `Bearer ${validToken}`)
.send({
auth: { type: 'wrongtype' }
})
expect(response.statusCode).toBe(400)
expect(response.body).toHaveProperty('errcode', 'M_INVALID_PARAM')
expect(response.body).toHaveProperty('error', 'Invalid auth')
})
it('should return 403 if the user is not an admin and the server does not allow it', async () => {
clientServer.conf.capabilities.enable_change_password = false
const response1 = await request(app)
Expand Down
Loading

0 comments on commit 34e91ac

Please sign in to comment.