npx skills add ...
npx skills add caffeinelabs/skills --skill extension-user-approval
Approval-based user management.
npx skills add caffeinelabs/skills --skill extension-user-approval
User approval extension for Caffeine AI.
This skill adds approval-based user management. Users request access; admins approve or reject. Approved users gain access to protected features.
Prerequisite: You must follow extension-authorization first, as this integration depends on it.
The prefabricated module mo:caffeineai-user-approval/approval provides low-level approval state management. Do not modify it.
include MixinUserApproval(accessControlState, approvalState) MUST be placed in main.mo, not in a custom mixin file. Declare approvalState at actor top level and pass it into the mixin. The mixin provides these public endpoints automatically:
isCallerApproved()requestApproval()setApproval(user, status)listApprovals()Keep approvalState in scope for custom approval guards in app-specific endpoints.
Do NOT redeclare any of the mixin-provided functions.
The migration chain head — UserApproval.initState depends on the access-control state, so compute it in order inside the migration body:
On initState, existing admins are automatically approved. All other users are pending.
IMPORTANT: Apply the right authorization and/or approval check to each custom public function.
Approval-based user management:
isCallerApproved)requestApproval)For admin users, provide a dashboard to:
listApprovals)setApproval)getCallerUserRole and assignCallerUserRole)The backend already implements the following functionality. The full interface can be found in
// Check if current user is approved, admins are always approved isCallerApproved(): Promise;
// Submit approval request requestApproval(): Promise;
// Get all users and their approval status (admin only) listApprovals(): Promise<Array>;
// Approve or reject a user (admin only) setApproval(user: Principal, status: ApprovalStatus): Promise;
// Assign a role to a user (admin only) assignCallerUserRole(user: Principal, role: UserRole): Promise;
// Get current role for a specific user getCallerUserRole(): Promise;