Skip to main content

robel-auth

Integrate and maintain Robelest Convex Auth in apps by always checking upstream before implementation. Use when adding auth setup, updating auth wiring, migrating between upstream patterns, or troubleshooting @robelest/convex-auth behavior across projects.

Ir a la instalación

Datos de origen

Repositorio
waynesutton/waynesutton-ai
Última actividad en el origen
17 de agosto de 2026 a las 06:37
Idioma detectado de SKILL.md
inglés
Estrellas
2
Forks
0

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
2 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
robel-auth
description
Integrate and maintain Robelest Convex Auth in apps by always checking upstream before implementation. Use when adding auth setup, updating auth wiring, migrating between upstream patterns, or troubleshooting @robelest/convex-auth behavior across projects.
# Robel auth skill Use this skill when a user asks to implement, update, or debug auth based on `robelest/convex-auth`. This skill is designed to be copied into other repos. ## Non negotiable upstream check before any auth change Run this every time before proposing code or commands. Preferred command: ```bash bash .agents/skills/robel-auth/scripts/check-upstream.sh ``` Manual checklist if script is unavailable: 1. Read official docs: `https://auth.estifanos.com/getting-started/installation/` 2. Read latest `main` README: `https://raw.githubusercontent.com/robelest/convex-auth/main/README.md` 3. Read latest `release` README: `https://raw.githubusercontent.com/robelest/convex-auth/release/README.md` 4. Check branch level differences: `https://github.com/robelest/convex-auth/compare/release...main` 5. Read current self hosting docs if portal or static hosting is involved: - `https://raw.githubusercontent.com/get-convex/self-hosting/main/INTEGRATION.md` - `https://github.com/get-convex/self-hosting` If `main` and `release` conflict, prefer the branch requested by the user. If unspecified, use `release` for stability and explain that choice. ## Important assumptions for this skill - Treat the official docs site (`auth.estifanos.com`) and GitHub as sources of truth every time. - Do not assume npm package availability. - Validate package availability at execution time. - If npm is unavailable, use a GitHub source install pinned to a branch or commit. - Keep all Convex code type safe and validator complete. ## Published package reality check (critical) The docs site (`auth.estifanos.com`) and `main` branch often describe APIs ahead of the latest preview release on npm. Before writing imports, always inspect what the installed version actually exports: ```bash ls node_modules/@robelest/convex-auth/dist/providers/ cat node_modules/@robelest/convex-auth/dist/providers/index.js cat node_modules/@robelest/convex-auth/dist/component/index.d.ts ``` As of `0.0.4-preview.25` the installed package ships: - PascalCase class/factory exports: `Password`, `OAuth`, `Passkey`, `Credentials`, `Anonymous`, `Device`, `Email`, `Phone`, `SSO`, `Totp` (not lowercase `password`, `oauth`, etc. that the docs show). - `Password`, `Credentials`, etc. are classes. Use `new Password()`, not `Password()`. - `OAuth` is a factory function: `OAuth(provider, config)`. - No first-party provider files exist yet (no `github.js`, `google.js`, etc.). For GitHub, Google, Apple, Microsoft, you still wrap an `arctic` provider in `OAuth()` and supply a `profile` callback. - `createAuth` is available from `@robelest/convex-auth/component` and is the correct entry point. - The client factory now **requires** `api` in SPA mode: `client({ convex, api: api.auth })`. Omitting `api` throws `"The \`api\` option is required when \`proxyPath\` is not set. Pass { api: api.auth }."` at first `signIn`/`signOut`/`verifyCode` call. Only `proxyPath` mode can skip it. If the docs show a lowercase factory like `github({ ... })` but the installed package only exports PascalCase classes and `OAuth`, follow the installed package and note the drift to the user. Do not blindly copy doc examples. ## Clarifying questions to ask first Ask these before editing: 1. Which branch is source of truth for this task, `release` or `main`. 2. Is this a new integration or an update to an existing auth setup. 3. Which framework is used: Vite, Next.js, SvelteKit, TanStack Start, Expo web, or other. 4. Is self hosted portal/static delivery needed now. 5. Are they okay pinning dependency to a specific Git commit for reproducibility. ## Install and dependency strategy Never assume one install path. 1. Try package registry lookup: - `npm view @robelest/convex-auth version` 2. If package is unavailable or blocked, install from GitHub: - `npm install github:robelest/convex-auth#release` 3. For deterministic builds, pin a commit SHA: - `npm install github:robelest/convex-auth#<commit-sha>` If the project uses pnpm or bun, translate the same GitHub dependency pinning pattern. ## Quick setup (CLI wizard) The recommended setup flow: 1. Install `@robelest/convex-auth` 2. Start a Convex deployment with `convex dev` 3. Run the auth setup wizard The wizard handles key generation, `convex.config.ts`, `auth.ts`, and `http.ts` automatically. ## Core wiring (3 files) ### 1. Register the component ```typescript // convex/convex.config.ts import { defineApp } from "convex/server"; import auth from "@robelest/convex-auth/convex.config"; const app = defineApp(); app.use(auth); export default app; ``` ### 2. Configure auth ```typescript // convex/auth.ts import { createAuth } from "@robelest/convex-auth/component"; import { components } from "./_generated/api"; import { github } from "@robelest/convex-auth/providers/github"; const auth = createAuth(components.auth, { providers: [ github({ clientId: process.env.AUTH_GITHUB_ID!, clientSecret: process.env.AUTH_GITHUB_SECRET!, }), ], }); export { auth }; export const { signIn, signOut, store } = auth; ``` ### 3. Wire up HTTP routes ```typescript // convex/http.ts import { httpRouter } from "convex/server"; import { auth } from "./auth"; const http = httpRouter(); auth.http.add(http); export default http; ``` `auth.http.add` registers OAuth callbacks and JWKS endpoints in one call. ## API layers Client auth flow: `signIn`, `signOut`, and `store` are the only required client-callable auth functions. Frontends use them through `client({ convex, api: api.auth })`. Server helpers: `auth.user.*`, `auth.session.*`, `auth.account.*`, `auth.group.*`, `auth.member.*`, `auth.invite.*`, `auth.key.*`, `auth.http.*`, `auth.group.sso.*`, and `auth.group.sso.scim.*` are server-side helpers for Convex code. They are not automatically public RPC. Optional group SSO RPC: If your app wants client-callable group SSO admin APIs, expose app-owned wrappers such as `convex/auth/group.ts`. ## Available providers All providers import from `@robelest/convex-auth/providers`: ```typescript import { anonymous, apple, custom, email, github, google, microsoft, passkey, password, phone, sso, totp, } from "@robelest/convex-auth/providers"; ``` ### OAuth providers | Provider | Factory | Required env vars | |----------|---------|-------------------| | GitHub | `github({ clientId, clientSecret })` | `AUTH_GITHUB_ID`, `AUTH_GITHUB_SECRET` | | Google | `google({ clientId, clientSecret })` | `AUTH_GOOGLE_ID`, `AUTH_GOOGLE_SECRET` | | Apple | `apple({ clientId, teamId, keyId, privateKey })` | `AUTH_APPLE_ID`, `AUTH_APPLE_TEAM_ID`, `AUTH_APPLE_KEY_ID`, `AUTH_APPLE_PRIVATE_KEY` | | Microsoft | `microsoft({ tenant, clientId, clientSecret? })` | `AUTH_MICROSOFT_TENANT_ID`, `AUTH_MICROSOFT_ID` | All OAuth wrappers derive callback URL from `CONVEX_SITE_URL` automatically. ### Custom OAuth Use `custom()` for providers without a first-party wrapper: ```typescript custom({ id: "discord", clientId: process.env.AUTH_DISCORD_ID!, clientSecret: process.env.AUTH_DISCORD_SECRET!, scopes: ["identify", "email"], authorization: { url: "https://discord.com/oauth2/authorize", pkce: "optional" }, token: { url: "https://discord.com/api/oauth2/token", authMethod: "body" }, profile: async ({ accessToken }) => { const res = await fetch("https://discord.com/api/users/@me", { headers: { Authorization: `Bearer ${accessToken}` }, }); const user = await res.json(); return { id: String(user.id), email: user.email, name: user.username }; }, }) ``` ### Non-OAuth providers | Provider | Factory | Notes | |----------|---------|-------| | Password | `password()` | Built-in password auth | | Magic links | `email({ from, send })` | Requires email transport (e.g. Resend) | | Passkeys | `passkey()` | WebAuthn based | | TOTP | `totp({ issuer })` | Authenticator app codes | | Anonymous | `anonymous()` | Guest sessions | | Phone/SMS | `phone({ send })` | Requires SMS transport (e.g. Twilio) | | Group SSO | `sso()` | Enables OIDC, SAML 2.0, SCIM 2.0 | ## Configuration options ```typescript const auth = createAuth(components.auth, { providers: [/* ... */], session: { totalDurationMs: 30 * 24 * 60 * 60 * 1000, // 30 days inactiveDurationMs: 7 * 24 * 60 * 60 * 1000, // 7 days }, jwt: { durationMs: 60 * 1000, // 1 minute }, signIn: { max_failed_attempts_per_hour: 10, }, callbacks: { afterUserCreatedOrUpdated: async (ctx, { userId, existingUser }) => { /* ... */ }, }, authorization: { roles, // from defineRoles() }, }); ``` | Option | Type | Default | Description | |--------|------|---------|-------------| | `providers` | `AuthProviderConfig[]` | required | Auth methods to enable | | `session.totalDurationMs` | `number` | 30 days | Maximum session lifetime | | `session.inactiveDurationMs` | `number` | varies | Inactive session timeout | | `jwt.durationMs` | `number` | 60s | JWT token lifetime | | `signIn.max_failed_attempts_per_hour` | `number` | 10 | Rate limit for failed sign-in attempts | | `callbacks.afterUserCreatedOrUpdated` | `function` | none | Post sign-in hook | | `authorization.roles` | `Record` | `{}` | App-defined role definitions and grants | ## Multi-access patterns Every auth path resolves to the same `userId`. Three access patterns: | Pattern | Context | How userId is available | |---------|---------|------------------------| | App code (query/mutation/action) | `auth.ctx()` | `ctx.auth.userId` and `ctx.auth.user` | | Raw HTTP (session or API key) | `auth.http.context(ctx, request)` | `authContext.userId` | | API key HTTP | `auth.http.action(...)` | `ctx.key.userId` | ### Auth-aware custom functions ```typescript // convex/functions.ts import { customMutation, customQuery } from "convex-helpers/server/customFunctions"; import { mutation, query } from "./_generated/server"; import { auth } from "./auth"; export const authQuery = customQuery(query, auth.ctx()); export const authMutation = customMutation(mutation, auth.ctx()); ``` Use `auth.ctx({ optional: true })` when the same handler should work for both guests and signed-in users. ### Raw HTTP mixed auth ```typescript http.route({ path: "/api/data", method: "GET", handler: httpAction(async (ctx, request) => { const authContext = await auth.http.context(ctx, request, { optional: true }); if (authContext.userId === null) { return new Response(JSON.stringify({ error: "Unauthorized" }), { status: 401 }); } const data = await ctx.runQuery(internal.data.forUser, { userId: authContext.userId }); return Response.json(data); }), }); ``` ## Authorization patterns ### Define roles with grants ```typescript import { defineRoles } from "@robelest/convex-auth/authorization"; export const roles = defineRoles({ orgAdmin: { label: "Organization Admin",
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub