Skip to content

Commit 95c8fee

Browse files
committed
feat: inactive users index
1 parent a82eb9b commit 95c8fee

6 files changed

Lines changed: 68 additions & 0 deletions

File tree

rfcs/inactive_users/user_index.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Inactive users index
2+
3+
## Overview and motivation
4+
As other task dependency and to provide additional internal statistics the Service needs additional index
5+
to track users that didn't pass the activation.
6+
7+
## `inactive-users` index
8+
It's an Additional Redis Sorted Set which contains the list of IDs of the `inactive` users.
9+
Each item score is equal to the `timestamp` set on user creation.
10+
11+
To avoid hardcoded SET name new `USERS_INACTIVATED` constant introduced.
12+
13+
## Inactive user tracking utils
14+
New `deleteFromInactiveUsers(userID)` and `addToInactiveUsers(userID)` methods used to control data stored inside `inactive-users` set.
15+
16+
## Registration process
17+
When the user succeeds registration but activation not requested, the new entry added to `inactive-users`.
18+
19+
**NOTE:** Old Redis `expire` setting methods left in their place, to save old service behavior.
20+
21+
## Activation process
22+
When the user succeeds activation the entry deleted from `inactive-users`.

src/actions/activate.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ const jwt = require('../utils/jwt.js');
55
const { getInternalData } = require('../utils/userData');
66
const getMetadata = require('../utils/getMetadata');
77
const handlePipeline = require('../utils/pipelineError.js');
8+
const { removeFromInactiveUsers } = require('../utils/inactiveUsers');
9+
810
const {
911
USERS_INDEX,
1012
USERS_DATA,
@@ -126,6 +128,9 @@ function activateAccount(data, metadata) {
126128
.persist(userKey)
127129
.sadd(USERS_INDEX, userId);
128130

131+
/* delete user id from the inactive users index */
132+
removeFromInactiveUsers(pipeline, userId);
133+
129134
if (alias) {
130135
pipeline.sadd(USERS_PUBLIC_INDEX, userId);
131136
}

src/actions/register.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ const checkLimits = require('../utils/checkIpLimits');
2222
const challenge = require('../utils/challenges/challenge');
2323
const handlePipeline = require('../utils/pipelineError');
2424
const hashPassword = require('../utils/register/password/hash');
25+
const { addToInactiveUsers } = require('../utils/inactiveUsers');
26+
2527
const {
2628
USERS_REF,
2729
USERS_INDEX,
@@ -208,7 +210,11 @@ async function performRegistration({ service, params }) {
208210
pipeline.hset(USERS_USERNAME_TO_ID, username, userId);
209211

210212
if (activate === false && config.deleteInactiveAccounts >= 0) {
213+
/* TODO Remove this line when last task in group merged */
211214
pipeline.expire(userDataKey, config.deleteInactiveAccounts);
215+
216+
/* Add user id to the inactive users index */
217+
addToInactiveUsers(pipeline, userId, audience);
212218
}
213219

214220
await pipeline.exec().then(handlePipeline);

src/actions/remove.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const getMetadata = require('../utils/getMetadata');
99
const handlePipeline = require('../utils/pipelineError');
1010
const {
1111
USERS_INDEX,
12+
USERS_INACTIVATED,
1213
USERS_PUBLIC_INDEX,
1314
USERS_ALIAS_TO_ID,
1415
USERS_SSO_TO_ID,
@@ -92,6 +93,9 @@ async function removeUser({ params }) {
9293
transaction.srem(USERS_PUBLIC_INDEX, userId);
9394
transaction.srem(USERS_INDEX, userId);
9495

96+
/* Delete user from the inactive users index, if user not activated */
97+
transaction.zrem(USERS_INACTIVATED, userId);
98+
9599
// remove metadata & internal data
96100
transaction.del(key(userId, USERS_DATA));
97101
transaction.del(key(userId, USERS_METADATA, audience));

src/constants.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ module.exports = exports = {
66
USERS_PUBLIC_INDEX: 'users-public',
77
USERS_REFERRAL_INDEX: 'users-referral',
88
ORGANIZATIONS_INDEX: 'organization-iterator-set',
9+
10+
/* inactive user ids set */
11+
USERS_INACTIVATED: 'users-inactivated',
12+
913
// id mapping
1014
USERS_ALIAS_TO_ID: 'users-alias',
1115
USERS_SSO_TO_ID: 'users-sso-hash',

src/utils/inactiveUsers/index.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const {
2+
USERS_INACTIVATED,
3+
} = require('../../constants');
4+
5+
/**
6+
* Add user id to inacive users list
7+
* @param {ioredis} redis
8+
* @param {userId} userId
9+
*/
10+
function addToInactiveUsers(redis, userId) {
11+
const created = Date.now();
12+
redis.zadd(USERS_INACTIVATED, created, userId);
13+
}
14+
15+
/**
16+
* Remove user id from inactive users list
17+
* @param {ioredis} redis
18+
* @param {userId} userId
19+
*/
20+
function removeFromInactiveUsers(redis, userId) {
21+
redis.zrem(USERS_INACTIVATED, userId);
22+
}
23+
24+
module.exports = {
25+
addToInactiveUsers,
26+
removeFromInactiveUsers,
27+
};

0 commit comments

Comments
 (0)