-
Notifications
You must be signed in to change notification settings - Fork 0
Allow sending email invites to people who are not already users on the platform #114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Core Problem: The current system only adds existing registered users directly to a role. We need a flow that:
High-Level Implementation Plan & Flow:
Detailed Component Breakdown:
This plan provides a comprehensive approach to adding a robust invitation system, handling various user states and ensuring security through token validation. Remember to handle database transactions carefully in the new/modified routes and helper functions. |
ChatGPT's effort to diagram in terms of functions and classes. Definitely needs some cleanup/optimization before we proceed. flowchart TD
subgraph "Invitation Creation"
direction LR
A_UI["User enters email/role in organization.html"] --> B_EP("POST /organizations/invite/ORG_ID <br> routers.organizations.invite_member")
B_EP --> C_Val{"Validation <br> Check Perms, Role, Member, Invite <br> Models: User, Org, Role, Invitation <br> Exceptions: UserIsAlreadyMemberError, ActiveInvitationExistsError"}
C_Val -- Valid --> D_Token["Generate Token <br> token = str(uuid4())"]
C_Val -- Invalid --> E_Err["Show Error / Redirect"]
D_Token --> F_DB_Create["Create Invitation Record <br> Model: Invitation <br> session.add(invitation)"]
F_DB_Create --> G_EmailTask["BackgroundTasks.add_task <br> send_invitation_email"]
G_EmailTask --> H_Commit["session.commit()"]
H_Commit --> I_Redirect["Redirect to organization.html <br> w/ Flash Message"]
subgraph "Email Sending (Background)"
direction TB
J_SendFunc("utils.invitations.send_invitation_email") --> K_LinkFunc("utils.invitations.generate_invitation_link")
K_LinkFunc --> L_Template("templates/emails/organization_invite.html")
L_Template --> M_Send["Send Email via Resend"]
end
G_EmailTask -.-> J_SendFunc
end
subgraph "Invitation Acceptance"
direction TB
N_Click["Invitee clicks link <br> GET /invitations/accept?token=TOKEN"]
--> O_EP("GET /invitations/accept <br> routers.invitations.accept_invitation")
O_EP --> P_TokenDep("Dependency: get_valid_invitation")
P_TokenDep --> Q_DB_Fetch["Fetch Invitation by Token <br> Model: Invitation"]
Q_DB_Fetch --> R_CheckActive{"Is Invitation Active? <br> invitation.is_active()"}
R_CheckActive -- Valid --> S_CheckAcct{"Account Exists? <br> Query Account by invitation.invitee_email"}
R_CheckActive -- Invalid --> T_ErrPage["Show Error Page <br> InvalidInvitationTokenError"]
S_CheckAcct -- Yes --> U_CheckLogin{"User Logged In? <br> Depends(get_optional_user)"}
S_CheckAcct -- No --> V_RedirectRegister["Redirect to <br> GET /account/register <br> w/ email & token"]
U_CheckLogin -- Yes --> W_CheckEmail{"Email Match? <br> current_user.account.email == invitee_email"}
U_CheckLogin -- No --> X_RedirectLogin["Redirect to <br> GET /account/login <br> w/ token"]
W_CheckEmail -- Yes --> Y_Process("Call process_invitation <br> utils.invitations.process_invitation")
W_CheckEmail -- No --> Z_EmailMismatch["Show Error Page <br> InvitationEmailMismatchError"]
Y_Process --> AA_DB_Update["Add User to Org/Role <br> Mark Invitation Used <br> session.commit()"]
AA_DB_Update --> AB_RedirectOrg["Redirect to <br> /organizations/ORG_ID"]
subgraph "Login Flow with Token"
direction TB
X_RedirectLogin --> BA_LoginGet("GET /account/login <br> routers.auth.login_get")
BA_LoginGet --> BB_LoginTmpl("templates/account/login.html <br> includes hidden token")
BB_LoginTmpl --> BC_UserLogin["User Submits Login Form"]
BC_UserLogin --> BD_LoginPost("POST /account/login <br> routers.auth.login_post")
BD_LoginPost --> BE_Auth{"Authenticate User"}
BE_Auth -- Success --> BF_CheckToken{"Has Invitation Token?"}
BF_CheckToken -- Yes --> BG_ValidateToken{"Validate Token & Email Match"}
BG_ValidateToken -- Valid --> BH_Process("Call process_invitation")
BH_Process --> AB_RedirectOrg
BF_CheckToken -- No --> BI_RedirectDash["Redirect to Dashboard"]
BG_ValidateToken -- Invalid --> T_ErrPage
end
subgraph "Registration Flow with Token"
direction TB
V_RedirectRegister --> CA_RegisterGet("GET /account/register <br> routers.auth.register_get")
CA_RegisterGet --> CB_RegisterTmpl("templates/account/register.html <br> pre-fills email, hidden token")
CB_RegisterTmpl --> CC_UserRegister["User Submits Registration Form"]
CC_UserRegister --> CD_RegisterPost("POST /account/register <br> routers.auth.register_post")
CD_RegisterPost --> CE_CreateUser{"Create User/Account"}
CE_CreateUser --> CF_CheckToken{"Has Invitation Token?"}
CF_CheckToken -- Yes --> CG_ValidateToken{"Validate Token & Email Match"}
CG_ValidateToken -- Valid --> CH_Process("Call process_invitation")
CH_Process --> AB_RedirectOrg
CF_CheckToken -- No --> CI_RedirectDash["Redirect to Dashboard"]
CG_ValidateToken -- Invalid --> T_ErrPage
end
end
%% Link Subgraphs
I_Redirect -.-> A_UI
M_Send -.-> N_Click
AB_RedirectOrg -.-> A_UI
BI_RedirectDash -.-> A_UI
CI_RedirectDash -.-> A_UI
class B_EP,O_EP,BD_LoginPost,BA_LoginGet,CD_RegisterPost,CA_RegisterGet endpoint;
class G_EmailTask,J_SendFunc,K_LinkFunc,P_TokenDep,Y_Process,BH_Process,CH_Process function;
class C_Val,F_DB_Create,Q_DB_Fetch,S_CheckAcct,AA_DB_Update,BE_Auth,BF_CheckToken,BG_ValidateToken,CE_CreateUser,CF_CheckToken,CG_ValidateToken db;
class L_Template,BB_LoginTmpl,CB_RegisterTmpl template;
class A_UI,N_Click,BC_UserLogin,CC_UserRegister ui;
class E_Err,T_ErrPage,Z_EmailMismatch error;
|
Currently the invite functionality on the organization page doesn't trigger any email flow. It only adds a user if they have already registered.
The text was updated successfully, but these errors were encountered: