-
Notifications
You must be signed in to change notification settings - Fork 9
Modules
Adrian Rocke edited this page Mar 1, 2025
·
2 revisions
- Authorizing user access to query data and perform actions
- A
Policydefines what roles are needed to perform an action. - For all policies, user claims are loaded to check system roles.
- If a language code is provided to the policy, language claims are also loaded to check language roles
import Policy from '@/modules/access/public/Policy'
// Requires either system admin or language admin role.
const policy = new Policy({
systemRoles: [Policy.SystemRole.Admin],
languageRoles: [Policy.LanguageRole.Admin]
})
// Loads user and language claims from the database to determine access
const isAuthorized = await policy.authorize({
actorId: 'user-id',
languageCode: 'spa'
})erDiagram
ActorClaims {
string id
SystemRole[] systemRoles
}
LanguageClaims {
string code
LanguageRole[] roles
}
Policy {
SystemRole[] systemRoles
LanguageRole[] languageRoles
}
- Reads from user and language module data to determine whether to authorize a user. This could be separated so it has it's own model that it derives from these modules through events.
- User identity
- Authentication
- Invitations
-
AcceptInvite- Takes a token and the users basic profile to complete their account setup -
ChangeUserRoles- Changes a user's system roles -
DisableUser- Disables the user so they can no longer log in or accept their invite -
InviteUser- Sends an email to a new user to invite the create an account -
LogIn- Verifies a user's password to log them into the system -
ProcessEmailRejection- Processes a bounce or a complaint of an email -
ResetPassword- Completes the reset password process with a new password -
StartPasswordReset- Sends an email to start the password reset -
UpdateProfile- Updates the users profile information, starts the email verification process if changed -
VerifyEmail- Uses a token to verify ownership over an email address waiting to be changed.
erDiagram
User{
string id
string name
UserEmail email
EmailVerifcation emailVerification
UserStatus status
Password password
PasswordReset[] passwordResets
Invitation[] invitation
}
User ||--o{ UserStatus : has
User }o--o{ SystemRole : has
UserEmail {
string address
EmailStatus status
}
User ||--|| UserEmail : has
UserEmail ||--o{ EmailStatus : has
EmailVerification {
string email
string token
Date expiresAt
}
EmailVerification ||--o| User : has
Password {
string hash
}
User |o--|| Password : has
PasswordReset {
string token
Date expiresAt
}
PasswordReset ||--o{ User : has
Session {
string id
string userId
Date expiresAt
}
Session ||..o{ User : references
Invitation {
string id
string userId
string token
Date expiresAt
}
Invitation ||--o{ User : has
erDiagram
reset_password_token{
~uuid~ user_id
~text~ token
~bigint~ expires
}
session{
~text~ id
~uuid~ user_id
~timestamp(3) without time zone~ expires_at
}
users{
~uuid~ id
~text~ name
~email_status~ email_status
~text~ email
~text~ hashed_password
~user_status~ status
}
user_email_verification{
~uuid~ user_id
~text~ email
~text~ token
~bigint~ expires
}
user_invitation{
~uuid~ user_id
~text~ token
~bigint~ expires
}
user_system_role{
~uuid~ user_id
~system_role~ role
}
session }|..|| users : session_user_id_fkey
user_email_verification }|..|| users : user_email_verification_user_id_fkey
user_invitation }|..|| users : user_invitation_user_id_fkey
user_system_role }|..|| users : user_system_role_user_id_fkey
reset_password_token }|..|| users : reset_password_token_user_id_fkey
- Disabling a user has side effects in other modules. Those should be decoupled through an event system, so that the users module is not responsible for executing those side effects.
- Currently has responsibility for handling email complaints and bounces. The block list from those events should be handled by a notifications module, while email verification (for ownership purposes) should still belong to the users module since it involves changing the user's profile.
- Currently has responsibility for maintaining a user's system roles. That could be transferred to the access control domain. At present those domains are going to be coupled since one writes the data and the other reads it.
- Language definition and configuration
- Language membership
-
ChangeLanguageMemberRoles- Changes a user's roles on the language - viewer, translator, admin -
CreateLanguage- Create a new language -
InviteLanguageMember- Invite a user to the language, and to the platform as well if necessary -
RemoveLanguageMember- Remove a user from a language -
RemoveUserFromLanguages- Remove a user from all languages - used when a user is disabled -
UpdateLanguageSettings- Update a language's configuration - name, font, translations, etc
erDiagram
Language{
string id
string name
string code
string font
TextDirection textDirection
string[] translationIds
}
LanguageMember{
string languageId
string userId
LanguageRole[] roles
}
LanguageMember ||..o{ Language : has
erDiagram
language{
~uuid~ id
~text~ code
~text~ name
~text~ font
~text[]~ translation_ids
~text_direction~ text_direction
}
language_import_job{
~uuid~ language_id
~timestamp(3) without time zone~ start_date
~timestamp(3) without time zone~ end_date
~boolean~ succeeded
~uuid~ user_id
}
language_member_role{
~uuid~ user_id
~uuid~ language_id
~language_role~ role
}
language_member_role }|..|| users : language_member_role_user_id_fkey
language_member_role }|..|| language : language_member_role_language_id_fkey
language_import_job }|..|| language : language_import_job_language_id_fkey
language_import_job }|..|| users : language_import_job_user_id_fkey
- Provides a use case for the users module to execute when a user is disabled. This should really be replaced by an event handler so as to not couple the two modules.
- Showing a list of members in the language requires access to a users name and email which is managed by the users module. This is loaded via a database query for now.