feat(auth): invite links for several people, invite by email, registration with approval or email domains
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m20s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m20s
- Invites: link /?invite=CODE, copy link, send by email, max uses with counter - Registration modes closed | approval | domain | domain+approval | open, waiting list with approve/reject - REGISTRATION_MODE / REGISTRATION_DOMAINS lock the admin setting; ALLOW_REGISTRATION=true is honoured Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
db5c5cde9b
commit
af77b9e809
24 files changed
+1077
-142
No files matched your search
+13
-3
@@ -271,12 +271,13 @@ export const api = {
|
||||
password: string,
|
||||
displayName: string,
|
||||
inviteCode?: string
|
||||
): Promise<{ token: string; user: User }> {
|
||||
const res = await request<{ token: string; user: User }>('/api/v1/auth/register', {
|
||||
): Promise<{ token?: string; user?: User; pending?: boolean; message?: string }> {
|
||||
const res = await request<{ token?: string; user?: User; pending?: boolean; message?: string }>('/api/v1/auth/register', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ email, password, displayName, inviteCode: inviteCode || '' }),
|
||||
});
|
||||
setToken(res.token);
|
||||
// Waiting for approval: no session yet
|
||||
if (res.token) setToken(res.token);
|
||||
return res;
|
||||
},
|
||||
|
||||
@@ -1121,6 +1122,7 @@ export const api = {
|
||||
email?: string;
|
||||
role: string;
|
||||
organizationId?: string;
|
||||
maxUses?: number;
|
||||
}): Promise<UserInvite> {
|
||||
return request<UserInvite>('/api/v1/admin/invites', {
|
||||
method: 'POST',
|
||||
@@ -1128,6 +1130,14 @@ export const api = {
|
||||
});
|
||||
},
|
||||
|
||||
async adminSendInvite(id: string, email: string): Promise<UserInvite> {
|
||||
return request<UserInvite>(`/api/v1/admin/invites/${id}/send`, { method: 'POST', body: JSON.stringify({ email }) });
|
||||
},
|
||||
|
||||
async adminApproveUser(id: string): Promise<User> {
|
||||
return request<User>(`/api/v1/admin/users/${id}/approve`, { method: 'POST' });
|
||||
},
|
||||
|
||||
async adminDeleteInvite(id: string): Promise<void> {
|
||||
await request(`/api/v1/admin/invites/${id}`, { method: 'DELETE' });
|
||||
},
|
||||
|
||||
@@ -2,9 +2,14 @@ export type ThoughtStatus = 'inbox' | 'kept' | 'discarded' | 'converted';
|
||||
export type PriorityLevel = 'low' | 'normal' | 'high' | 'urgent';
|
||||
export type UserRole = 'admin' | 'member';
|
||||
|
||||
export type RegistrationMode = 'closed' | 'approval' | 'domain' | 'domain+approval' | 'open';
|
||||
|
||||
export interface AuthStatus {
|
||||
needsSetup: boolean;
|
||||
allowRegistration: boolean;
|
||||
// Registering without an invite and the e-mail domains of the domain modes (hint on the form)
|
||||
registrationMode?: RegistrationMode;
|
||||
registrationDomains?: string[];
|
||||
instanceName: string;
|
||||
demoMode?: boolean;
|
||||
sharingMode?: SharingMode;
|
||||
@@ -94,6 +99,8 @@ export interface User {
|
||||
avatarUrl?: string;
|
||||
role: UserRole;
|
||||
isActive: boolean;
|
||||
// Registered and waiting for an admin's approval (admin user list)
|
||||
pendingApproval?: boolean;
|
||||
alarmChannels?: string[];
|
||||
alarmEmail?: string;
|
||||
discordWebhookUrl?: string;
|
||||
@@ -115,6 +122,9 @@ export interface UserInvite {
|
||||
usedBy?: string;
|
||||
createdAt: string;
|
||||
expiresAt: string;
|
||||
// A link for several people: allowed and used redemptions
|
||||
maxUses: number;
|
||||
useCount: number;
|
||||
}
|
||||
|
||||
export interface SubTask {
|
||||
@@ -250,6 +260,10 @@ export interface SystemSettings {
|
||||
smtpSkipVerify?: boolean;
|
||||
allowPrivateWebhooks?: boolean; // alarm webhooks may reach the LAN (and plain http)
|
||||
smtpConfiguredViaEnv?: boolean;
|
||||
registrationMode?: RegistrationMode;
|
||||
registrationDomains?: string;
|
||||
// REGISTRATION_MODE / REGISTRATION_DOMAINS (or ALLOW_REGISTRATION=true) fix it: shown, not editable
|
||||
registrationConfiguredViaEnv?: boolean;
|
||||
// Automatic backups: daily time (HH:MM, server time zone) and days to keep them
|
||||
backupEnabled?: boolean;
|
||||
backupTime?: string;
|
||||
|
||||
Reference in new issue
Block a user