caffeinelabs/skills

extension-user-approval

Approval-based user management.

Ver código fuente
Documento original del Skill

Contenido del repositorio de origen con títulos, ejemplos, código, tablas, enlaces e imágenes preservados.

User Approval

User approval extension for Caffeine AI.

Overview

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.

Backend

Module API

The prefabricated module mo:caffeineai-user-approval/approval provides low-level approval state management. Do not modify it.

mo:caffeineai-user-approval/approval
import AccessControl "mo:caffeineai-authorization/access-control";

module {
    public type ApprovalStatus = {
        #approved;
        #rejected;
        #pending;
    };

    public type UserApprovalState = { /* internal state */ };

    public func initState(accessControlState: AccessControl.AccessControlState) : UserApprovalState;

    public func isApproved(state : UserApprovalState, caller : Principal) : Bool;
    public func requestApproval(state : UserApprovalState, caller : Principal);
    public func setApproval(state : UserApprovalState, user : Principal, approval : ApprovalStatus);

    public type UserApprovalInfo = {
        principal : Principal;
        status : ApprovalStatus;
    };

    public func listApprovals(state : UserApprovalState) : [UserApprovalInfo];
}

Setup in main.mo

include MixinUserApproval(accessControlState, approvalState) MUST be placed in main.mo, not in a custom mixin file. Create approvalState at actor top level with UserApproval.initState(accessControlState) 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.

motoko
import AccessControl "mo:caffeineai-authorization/access-control";
import MixinAuthorization "mo:caffeineai-authorization/MixinAuthorization";
import MixinUserApproval "mo:caffeineai-user-approval/MixinUserApproval";
import UserApproval "mo:caffeineai-user-approval/approval";
import Runtime "mo:core/Runtime";

actor {
    let accessControlState = AccessControl.initState();
    include MixinAuthorization(accessControlState, null);
    let approvalState = UserApproval.initState(accessControlState);
    include MixinUserApproval(accessControlState, approvalState);

    // Example custom endpoint with an approval guard:
    // public shared ({ caller }) func protectedFeature() : async () {
    //     if (not (UserApproval.isApproved(approvalState, caller) or AccessControl.hasPermission(accessControlState, caller, #admin))) {
    //         Runtime.trap("Unauthorized: Only approved users can perform this action");
    //     };
    // };
};

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.

Frontend

Approval-based user management:

User Approval Flow

  • Check approval status (isCallerApproved)
  • If not approved, show option to request approval (requestApproval)
  • Block access to main features for non-approved users
  • Admins have access to all features of the application
  • Display approval status clearly in the UI

Admin Dashboard

For admin users, provide a dashboard to:

  • List all users with their approval status (listApprovals)
  • Approve or reject users (setApproval)
  • View and assign user roles (using getCallerUserRole and assignCallerUserRole)

Backend Integration

The backend already implements the following functionality. The full interface can be found in <backend-interface>

// Check if current user is approved, admins are always approved isCallerApproved(): Promise<boolean>;

// Submit approval request requestApproval(): Promise<void>;

// Get all users and their approval status (admin only) listApprovals(): Promise<Array<UserApprovalInfo>>;

// Approve or reject a user (admin only) setApproval(user: Principal, status: ApprovalStatus): Promise<void>;

// Assign a role to a user (admin only) assignCallerUserRole(user: Principal, role: UserRole): Promise<void>;

// Get current role for a specific user getCallerUserRole(): Promise<UserRole>;

del mismo repositorio

Más Skills

Todos los Skills
caffeinelabs
Comunidad

connector-googlecalendar

- MANDATORY recipe for every Caffeine build that lists upcoming events or creates events on the user's own Google Calendar. The ONLY supported path is the googlecalendar-client mops package (Calendar REST API v3) combined with the google-oauth mops package (token exchange + refresh + PKCE). Hand-rolling ic.httprequest calls to oauth2.googleapis.com or www.googleapis.com/calendar/v3 is a FORBIDDEN anti-pattern — it bypasses bearer auth, replication-cost safeguards, and the google-oauth library's percent-encoding and JSON parsing. Load this skill whenever the user, spec, or any prior task mentions scheduling, calendar events, appointments, meetings, "add to calendar", or any equivalent phrasing — and BEFORE writing any code that touches a Google endpoint.

instalaciones
2
GitHub Stars
0
Actualizado
4 sept
caffeinelabs
Comunidad

connector-googlemail

- MANDATORY recipe for every Caffeine build that sends email through the user's own Gmail account. The ONLY supported path is the googlemail-client mops package (Gmail REST API) combined with the google-oauth mops package (token exchange + refresh + PKCE). Hand-rolling ic.httprequest calls to oauth2.googleapis.com or gmail.googleapis.com is a FORBIDDEN anti-pattern — it bypasses bearer auth, replication-cost safeguards, and the google-oauth library's percent-encoding and JSON parsing. Load this skill whenever the user, spec, or any prior task mentions sending email, Gmail, "notify via email", "forward results by email", or any equivalent phrasing — and BEFORE writing any code that touches a Google endpoint.

instalaciones
2
GitHub Stars
0
Actualizado
4 sept
caffeinelabs
Comunidad

connector-slack

- EXPERIMENTAL, UNTESTED recipe for posting messages to a Slack workspace from a Caffeine canister via the slack-client mops package (Slack Web API). Use it when the user wants their app to send a message to a Slack channel — "post to Slack", "notify a channel", "send a Slack message", or equivalent. The client is a pre-release 0.1.0 drop (bot xoxb- or user xoxp- token): its request path is verified against the live Slack API (a real message posts), but the success-response decode is not yet runtime-confirmed, so treat it as a starting point and do NOT present Slack as a fully supported platform feature yet. Hand-rolling ic.httprequest calls to slack.com/api is still the wrong move — prefer the generated client so bearer auth, percent-encoding, and JSON parsing come for free.

instalaciones
2
GitHub Stars
0
Actualizado
4 sept
caffeinelabs
Comunidad

connector-twilio

- EXPERIMENTAL, NOT YET VERIFIED AGAINST LIVE TWILIO, and it spends real money — every message is billed, and a US-bound production number additionally needs A2P 10DLC registration (fees, weeks of lead time). Say both things to the user before building. That said, if a Caffeine build does send SMS or MMS, or configures Twilio messaging, from a canister, the twilio-client mops package (Twilio REST API) with a canister-held HTTP Basic credential is the only supported path. Hand-rolling ic.httprequest calls to api.twilio.com or messaging.twilio.com is a FORBIDDEN anti-pattern — it bypasses the typed bindings, the per-operation host routing, the Basic-Auth header construction, and above all the non-replicated outcall default that stops one send from becoming ~13 billed messages. Load this skill whenever the user, spec, or any prior task mentions SMS, MMS, "text message", "send a text", phone numbers, Twilio, a Messaging Service, A2P 10DLC, toll-free verification, short codes, or an alphanumeric sender — and BEFORE writing any code that touches a Twilio endpoint.

instalaciones
2
GitHub Stars
0
Actualizado
4 sept