Skip to main content

User Management Service

User management service is responsible to manage User accounts and authentication.

User Account contains information about a user

Non exhaustive list of

  • AccountID : Uniquely idenfity the account, and is used as login. Usually email address
  • List of Profiles, each profiles define participants with avatar and nickname and

Profiles define participants associated with the account. In the User Service only potentially identifying fields are registered like a nickname (could be a real name) and an avatar (image name selected by participant that could indirectly give little information about the participant).

Profiles are not directly connected to the response data, but Profile Id are mapped to a ParticipantID using a Mapping operator in the Study Service.

User Account Data structure

interface User {
account: {
type: string // Type of account 'email' for email authentication type
accountID: string // ID of the account, used as login
accountConfirmedAt: number // Timestamp of the confirmation of the account (when confirmation link is clicked in email sent on account creation )
password: string // Hashed password (using Argon2)
authType: string
preferredLanguage: string // Language code of the preferred to use as default in the web interface
},
roles: string[] // List of main roles of the account `PARTICIPANT`, `RESEARCHER`, `ADMIN`
timesptamps: {

},
profiles: Profile[], // List of participant associated with the account
contactPreferences: {
subscribedToNewsletter: bool,
SendNewsletterTo: string[],
subscribedToWeekly: bool
receiveWeeklyMessageDayOfWeek: number
}
contactInfos: ContactInfo[]
}

interface Profile {
_id?: string // ProfileID, used to
alias?: string // Participant's nickname
consentConfirmedAt: number
createdAt: number
avatarID?: string // Name of the image selected for this participant
mainProfile: boolean // if True, this is the "main" profile,
}

interface ContactInfo {
_id: string // Id of contact, used in contactPreferences.SendNewsletterTo
type: string // Kind of contact, 'email','phone'
confirmedAt: number // Timestamp of verficiation, 0 = not verified
confirmationLinkSentAt: number // Timestamp of the last verification email sent
email?: string
phone?: string
}

User Service

Features provided by the User Service

  • Create and update User account
  • Validate account creation by confirmation email
  • Validate User contact info by sending confirmation email
  • Manage Authentication Tokens
  • Manage Password Reset endpoint
  • Manage Temporary tokens

Inside the service some time based operation can be

  • Cleanup unverified users after a delay
  • Send Reminder to confirm account creation

Golang Implementation

The golang implementation of https://github.com/influenzanet/user-management-service

Service configuration

User management service is configured using Environment variables.

Environment list is defined in https://github.com/influenzanet/user-management-service/blob/master/build/docker/example/user-management-env.list

Database connexions

USER_DB_CONNECTION_STR=<mongodb-atlas-or-other-server-e.g.xxxx.mongodb.net/test?retryWrites=true&w=majority>
USER_DB_CONNECTION_PREFIX=<emtpy or +srv if atlas>
USER_DB_USERNAME=<db-username>
USER_DB_PASSWORD=<db-password>

GLOBAL_DB_CONNECTION_STR=<mongodb-atlas-or-other-server-e.g.xxxx.mongodb.net/test?retryWrites=true&w=majority>
GLOBAL_DB_CONNECTION_PREFIX=<emtpy or +srv if atlas>
GLOBAL_DB_USERNAME=<db-username>
GLOBAL_DB_PASSWORD=<db-password>

DB_TIMEOUT=30
DB_IDLE_CONN_TIMEOUT=45
DB_MAX_POOL_SIZE=8
DB_DB_NAME_PREFIX=

Databases organization is described in Architecture

DB_DB_NAME_PREFIX used as the Database Prefix name, all databases manages by the service will use this value as a prefix.

USER_DB_* is needed to connect to the User Databases for all the managed instances. It should be credentials of an account with read/write rights on all databases of the managed instances.

GLOBAL_DB_* is needed to connect to the Global Databases for this prefix. (containing the instances collection)

*_CONNECTION_PREFIX is used for the connexion schema, if you use domain based load balancer you can use '+srv' prefix, or leave empty.

Authentication settings

  • TOKEN_EXPIRATION_MIN : Token expiration delay (in minutes)
  • JWT_TOKEN_KEY: Random generated base64 encoded key, should be secret
  • ARGON2_MEMORY: Memory to use for Argon2 password Hashing
  • ARGON2_ITERATIONS: Number of Iterations to used
  • ARGON2_PARALLELISM: Number of thread to use to compute Argon2 password hashing

For details about Argon2, the golang package can give some help https://pkg.go.dev/golang.org/x/crypto/argon2

Service Connection

  • USER_MANAGEMENT_LISTEN_PORT: Value of the port the service will listen

The User Service need to connect to other services, host:port address must be specified as

  • ADDR_MESSAGING_SERVICE : Messaging Service Address
  • ADDR_LOGGING_SERVICE: Logging Service Address

Parameters for User services behaviors

Duration and Lifetimes | Variable | Description | Unit | |------------------------------------- |--------------------------------------------------------|-----------------------------| | CLEAN_UP_UNVERIFIED_USERS_AFTER | Number of seconds period to cleanup unverified account | seconds | | VERIFICATION_CODE_LIFETIME | Lifetime of the verification code for a new account | seconds | | INVITATION_TOKEN_LIFETIME | Token lifetime for Invitation message | Duration (default: minutes) | | CONTACT_VERIFICATION_TOKEN_LIFETIME | Token lifetime for Contact verification (email) | Duration (default: minutes) |

(*) Duration handles unit (golang time.Duration 'h' for hours, 'm' for minutes, 's' for seconds), if unit is not indicated in the value the unit between parenthesis will be used.

  • NEW_USER_RATE_LIMIT: Maximum number of new created accounts, during the signupRateLimitWindow (5 minutes)

WeekDay assignation

  • WEEKDAY_ASSIGNATION_WEIGHTS : Weight of days

Each account is assigned to a random day of the week to receive the Weekly reminder/newsletter. To control distribution of accounts on week days, it's possible to give a weight to each day. The weight will be used to determine the probability to assign a user to a given day. The probability to assign a day is given by P(day) = W(day) / Sum(W(0)..W(7)) It's up to you to define weights, you can use any positive integer. If Weight of a day is set to 0, then the day will be excluded and no account will be assigned to this day. Each day is named by its 3 letter abbreviation (case insensitive) : Mon, Tue, Wed, Thu, Fri, Sat, Sun

Examples:

# Uniform assignation (each day has the same probability to be picked up), it's the default strategy if no value is given for this variable
WEEKDAY_ASSIGNATION_WEIGHTS=Mon=1,Tue=1,Wed=1,Thu=1,Fri=1,Sat=1,Sun=1

# Only Monday - Webnesday
WEEKDAY_ASSIGNATION_WEIGHTS=Mon=1,Tue=1,Wed=1,Thu=0,Fri=0,Sat=0,Sun=0

# Only Monday - Thursday, but Tuesday, Wednesday twice a chance to be choosen
WEEKDAY_ASSIGNATION_WEIGHTS=Mon=1,Tue=2,Wed=2,Thu=1,Fri=0,Sat=0,Sun=0