From aa721ce8a3e5e0595d055a1d2847fc30f807a4ce Mon Sep 17 00:00:00 2001 From: Oleg Tokar Date: Sun, 9 Feb 2025 12:30:36 +0200 Subject: [PATCH 1/9] fix: remove contact email from username --- Dockerfile | 1 + src/actions/contacts/remove.js | 6 +++--- src/utils/contacts.js | 11 ++++++----- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Dockerfile b/Dockerfile index 326fd1ba5..f1e36bd74 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,7 @@ RUN \ apk --update --upgrade \ add ca-certificates --virtual .buildDeps git ca-certificates openssl g++ make python3 linux-headers \ && update-ca-certificates \ + && npm i -g corepack@latest \ && corepack install -g pnpm@9 \ && chown node:node /src \ && su node sh -c "cd /src && pnpm fetch --prod" \ diff --git a/src/actions/contacts/remove.js b/src/actions/contacts/remove.js index 3eca24cf7..ac48d6cd1 100644 --- a/src/actions/contacts/remove.js +++ b/src/actions/contacts/remove.js @@ -13,9 +13,9 @@ const { getUserId } = require('../../utils/userData'); * * @apiParam (Payload) {String} username - */ -module.exports = async function remove({ params }) { - const userId = await getUserId.call(this, params.username); - return contacts.remove.call(this, { contact: params.contact, userId }); +module.exports = async function remove({ params: { username, contact } }) { + const userId = await getUserId.call(this, username); + return contacts.remove.call(this, { contact, userId }); }; module.exports.transports = [ActionTransport.amqp, ActionTransport.internal]; diff --git a/src/utils/contacts.js b/src/utils/contacts.js index 627a7570d..d50306faf 100644 --- a/src/utils/contacts.js +++ b/src/utils/contacts.js @@ -64,11 +64,8 @@ async function removeAllEmailContactsOfUser(redisPipe, userId, exceptEmail) { } } -async function replaceUserName(redisPipe, userId, verifiedEmail) { +async function setUserName(redisPipe, userId, verifiedEmail) { const { config: { jwt: { defaultAudience } } } = this; - const internalData = await getInternalData.call(this, userId); - const username = internalData[USERS_USERNAME_FIELD]; - redisPipe.hdel(USERS_USERNAME_TO_ID, username); redisPipe.hset(USERS_USERNAME_TO_ID, verifiedEmail, userId); redisPipe.hset(redisKey(userId, USERS_DATA), USERS_USERNAME_FIELD, verifiedEmail); redisPipe.hset(redisKey(userId, USERS_METADATA, defaultAudience), USERS_USERNAME_FIELD, JSON.stringify(verifiedEmail)); @@ -176,7 +173,7 @@ async function verifyEmail({ secret }) { await removeAllEmailContactsOfUser.call(this, pipe, userId, contact.value); } if (this.config.contacts.updateUsername) { - await replaceUserName.call(this, pipe, userId, contact.value); + await setUserName.call(this, pipe, userId, contact.value); } pipe.hset(key, 'verified', 'true'); metadata.contact.verified = true; @@ -241,6 +238,10 @@ async function remove({ userId, contact }) { pipe.del(key); pipe.srem(redisKey(userId, USERS_CONTACTS), contact.value); + if (this.config.contacts.updateUsername) { + pipe.hdel(USERS_USERNAME_TO_ID, contact.value); + } + return pipe.exec().then(handlePipeline); } From 6add4b75347ee8d0b121e53b7ddcf0d1c6a376d1 Mon Sep 17 00:00:00 2001 From: Oleg-Tokar Date: Mon, 10 Feb 2025 06:57:07 +0200 Subject: [PATCH 2/9] fix: test added --- Dockerfile | 1 - src/actions/contacts/remove.js | 6 +++--- src/utils/contacts.js | 2 +- test/suites/actions/contacts.js | 22 ++++++++++++++++++++++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index f1e36bd74..326fd1ba5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,6 @@ RUN \ apk --update --upgrade \ add ca-certificates --virtual .buildDeps git ca-certificates openssl g++ make python3 linux-headers \ && update-ca-certificates \ - && npm i -g corepack@latest \ && corepack install -g pnpm@9 \ && chown node:node /src \ && su node sh -c "cd /src && pnpm fetch --prod" \ diff --git a/src/actions/contacts/remove.js b/src/actions/contacts/remove.js index ac48d6cd1..3eca24cf7 100644 --- a/src/actions/contacts/remove.js +++ b/src/actions/contacts/remove.js @@ -13,9 +13,9 @@ const { getUserId } = require('../../utils/userData'); * * @apiParam (Payload) {String} username - */ -module.exports = async function remove({ params: { username, contact } }) { - const userId = await getUserId.call(this, username); - return contacts.remove.call(this, { contact, userId }); +module.exports = async function remove({ params }) { + const userId = await getUserId.call(this, params.username); + return contacts.remove.call(this, { contact: params.contact, userId }); }; module.exports.transports = [ActionTransport.amqp, ActionTransport.internal]; diff --git a/src/utils/contacts.js b/src/utils/contacts.js index d50306faf..e42e7d54e 100644 --- a/src/utils/contacts.js +++ b/src/utils/contacts.js @@ -3,7 +3,7 @@ const { HttpStatusError } = require('@microfleet/validation'); const challengeAct = require('./challenges/challenge'); const redisKey = require('./key'); const handlePipeline = require('./pipeline-error'); -const { getInternalData, getUserId } = require('./userData'); +const { getUserId } = require('./userData'); const { USERS_CONTACTS, USERS_DEFAULT_CONTACT, diff --git a/test/suites/actions/contacts.js b/test/suites/actions/contacts.js index 2fa4b7010..f4987b002 100644 --- a/test/suites/actions/contacts.js +++ b/test/suites/actions/contacts.js @@ -4,6 +4,7 @@ const { faker } = require('@faker-js/faker'); const sinon = require('sinon'); const { createMembers } = require('../../helpers/organization'); const { startService, clearRedis } = require('../../config'); +const { USERS_USERNAME_TO_ID } = require('../../../src/constants'); describe('#user contacts', function registerSuite() { const audience = '*.localhost'; @@ -288,4 +289,25 @@ describe('#user contacts', function registerSuite() { assert.equal(name, params.metadata.name); amqpStub.restore(); }); + + it('should remove username to userid mapping on contact removal', async function test() { + const params = { + username: this.testUser.username, + contact: { + value: 'email@mail.org', + type: 'email', + }, + }; + await this.users.dispatch('contacts.add', { params }); + const amqpStub = sinon.stub(this.users.amqp, 'publish'); + amqpStub.withArgs('mailer.predefined').resolves({ queued: true }); + await this.users.dispatch('contacts.challenge', { params }); + const { ctx: { template: { token: { secret } } } } = amqpStub.args[0][1]; + await this.users.dispatch('contacts.verify-email', { params: { secret } }); + const userid = await this.users.redis.hget(USERS_USERNAME_TO_ID, params.contact.value); + assert.notEqual(userid, null); + await this.users.dispatch('contacts.remove', { params }); + const useridRemoved = await this.users.redis.hget(USERS_USERNAME_TO_ID, params.contact.value); + assert.equal(useridRemoved, null); + }); }); From 081e70c4bed110f204c3650893c62c1c55bb61ef Mon Sep 17 00:00:00 2001 From: Oleg-Tokar Date: Mon, 10 Feb 2025 07:18:05 +0200 Subject: [PATCH 3/9] fix: test added --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 326fd1ba5..f2c9c7430 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ RUN \ apk --update --upgrade \ add ca-certificates --virtual .buildDeps git ca-certificates openssl g++ make python3 linux-headers \ && update-ca-certificates \ - && corepack install -g pnpm@9 \ + && corepack install -g pnpm@9.15.4 \ && chown node:node /src \ && su node sh -c "cd /src && pnpm fetch --prod" \ && su node sh -c "rm -rf ~/.cache && pnpm store prune" \ From d50e08a63e76265286477e0c59fb673c7b79a0ed Mon Sep 17 00:00:00 2001 From: Oleg-Tokar Date: Mon, 10 Feb 2025 13:27:28 +0200 Subject: [PATCH 4/9] fix: docker --- .mdeprc.js | 2 +- Dockerfile | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.mdeprc.js b/.mdeprc.js index 460c47704..8d49f9906 100644 --- a/.mdeprc.js +++ b/.mdeprc.js @@ -14,7 +14,7 @@ if (os.platform() !== 'darwin') { } catch (e) { } } -exports.node = "20"; +exports.node = "22.13.1"; exports.in_one = true; exports.auto_compose = true; exports.with_local_compose = true; diff --git a/Dockerfile b/Dockerfile index f2c9c7430..28732fd8f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,7 @@ FROM makeomatic/node:$NODE_VERSION ENV NCONF_NAMESPACE=MS_USERS \ - NODE_ENV=$NODE_ENV \ - COREPACK_ENABLE_NETWORK=1 + NODE_ENV=$NODE_ENV WORKDIR /src @@ -12,7 +11,6 @@ RUN \ apk --update --upgrade \ add ca-certificates --virtual .buildDeps git ca-certificates openssl g++ make python3 linux-headers \ && update-ca-certificates \ - && corepack install -g pnpm@9.15.4 \ && chown node:node /src \ && su node sh -c "cd /src && pnpm fetch --prod" \ && su node sh -c "rm -rf ~/.cache && pnpm store prune" \ From a69e3100986159357f2e108dab0be2059770b324 Mon Sep 17 00:00:00 2001 From: Oleg-Tokar Date: Mon, 10 Feb 2025 13:36:05 +0200 Subject: [PATCH 5/9] fix: docker --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 0fc0b3ef5..784304094 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,6 @@ `npm i ms-users -S` ## Overview - Starts horizontally scalable nodejs worker communicating over amqp layer with redis cluster backend. Supports a broad range of operations for working with users. Please refer to the configuration options for now, that contains description of routes and their capabilities. Aims to provide a complete extendable solution to user's management. From ac2c0f3a0ce194622a57766fa88e081d4fc3abaa Mon Sep 17 00:00:00 2001 From: Oleg-Tokar Date: Mon, 10 Feb 2025 13:56:19 +0200 Subject: [PATCH 6/9] fix: test --- README.md | 1 + test/suites/actions/invite.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 784304094..0fc0b3ef5 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ `npm i ms-users -S` ## Overview + Starts horizontally scalable nodejs worker communicating over amqp layer with redis cluster backend. Supports a broad range of operations for working with users. Please refer to the configuration options for now, that contains description of routes and their capabilities. Aims to provide a complete extendable solution to user's management. diff --git a/test/suites/actions/invite.js b/test/suites/actions/invite.js index 7efda6e1d..16f9d0104 100644 --- a/test/suites/actions/invite.js +++ b/test/suites/actions/invite.js @@ -78,7 +78,7 @@ describe('#invite', function registerSuite() { audience: '*.localhost', } }), { name: 'AssertionError', - message: `Sanity check failed for "id" failed: "abnormal@yandex.ru" vs "${email}"`, + message: `Sanity check failed for "id" failed: "abnormal@yandex.ru" vs "${email}"\n`, }); }); From db3465f4f4381755981e6c1649d889f7fa07b085 Mon Sep 17 00:00:00 2001 From: Oleg-Tokar Date: Mon, 10 Feb 2025 14:01:04 +0200 Subject: [PATCH 7/9] fix: test --- test/suites/actions/invite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/suites/actions/invite.js b/test/suites/actions/invite.js index 16f9d0104..bca392ed9 100644 --- a/test/suites/actions/invite.js +++ b/test/suites/actions/invite.js @@ -78,7 +78,7 @@ describe('#invite', function registerSuite() { audience: '*.localhost', } }), { name: 'AssertionError', - message: `Sanity check failed for "id" failed: "abnormal@yandex.ru" vs "${email}"\n`, + message: 'Sanity check failed for "id" failed: "abnormal@yandex.ru" vs "v@yandex.ru"', }); }); From 4b3e3cbe04a3c5720d8ee7d8f6f821cfc7df22b9 Mon Sep 17 00:00:00 2001 From: Oleg-Tokar Date: Mon, 10 Feb 2025 14:08:56 +0200 Subject: [PATCH 8/9] fix: test1 --- test/suites/actions/invite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/suites/actions/invite.js b/test/suites/actions/invite.js index bca392ed9..464c17534 100644 --- a/test/suites/actions/invite.js +++ b/test/suites/actions/invite.js @@ -78,7 +78,7 @@ describe('#invite', function registerSuite() { audience: '*.localhost', } }), { name: 'AssertionError', - message: 'Sanity check failed for "id" failed: "abnormal@yandex.ru" vs "v@yandex.ru"', + message: 'Sanity check failed for "id" failed: "abnormal@yandex.ru"\n vs "v@yandex.ru"\n', }); }); From 22ad6cde765806c72628f4bae4b33824d9fb3e56 Mon Sep 17 00:00:00 2001 From: Oleg Tokar Date: Mon, 10 Feb 2025 16:46:46 +0200 Subject: [PATCH 9/9] fix: test assert was changed 22 node in ms-token --- test/suites/actions/invite.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/suites/actions/invite.js b/test/suites/actions/invite.js index 464c17534..81b6f033d 100644 --- a/test/suites/actions/invite.js +++ b/test/suites/actions/invite.js @@ -76,9 +76,10 @@ describe('#invite', function registerSuite() { password: '123', inviteToken: this.invitationToken, audience: '*.localhost', - } }), { - name: 'AssertionError', - message: 'Sanity check failed for "id" failed: "abnormal@yandex.ru"\n vs "v@yandex.ru"\n', + } }), (err) => { + assert.strictEqual(err.name, 'AssertionError'); + assert.match(err.message, /Sanity check failed for "id" failed: "abnormal@yandex.ru" vs "v@yandex.ru"/); + return true; }); });