Add shared port registry workflow and improve scaffold tooling
This commit is contained in:
69
resources/skills/discord-oauth-vue3-vite/SKILL.md
Normal file
69
resources/skills/discord-oauth-vue3-vite/SKILL.md
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
name: discord-oauth-vue3-vite
|
||||
description: "Use when scaffolding Discord OAuth into a Vue 3 + Vite app with a server bundle under src/server, PKCE, session handling, and route protection."
|
||||
argument-hint: "project-root=<path> mode=<dry-run|apply> frontend-origin=<url> allowlist-discord-ids=<csv>"
|
||||
---
|
||||
|
||||
# Discord OAuth Vue 3 + Vite
|
||||
|
||||
Use this skill when you want a portable, repeatable Discord OAuth setup for a Vue 3 + Vite app and you want the server-side auth bundle kept under `src/server/` instead of a standalone `scripts/` service.
|
||||
|
||||
## Procedure
|
||||
|
||||
### Server bundle
|
||||
|
||||
1. Confirm the target project root and review the generated server bundle path, which defaults to `src/server/discord-oauth`.
|
||||
2. Confirm the user-owned prerequisites: a Discord application, the authorized redirect URI, client ID, client secret, and any Discord user IDs that should be allowlisted.
|
||||
3. Run `resources/scripts/scaffold-discord-oauth-vue3-vite.sh` in `--mode dry-run` first when the shared resources repo is available; if the script path is not available in the current workspace, continue with the manual scaffold path instead of stopping.
|
||||
4. Let the scaffold create the auth bundle under `src/server/` with PKCE state handling, Discord token exchange, profile fetch, allowlist checks, refresh-session rotation, and logout cleanup.
|
||||
5. Copy the generated `clients.example.json` to `clients.json` and fill in the Discord client credentials and frontend origin values.
|
||||
6. Set `AUTH_PORT`, `JWT_SECRET`, and the other auth env vars locally. Align the Discord redirect URI with the app callback route (`<frontendOrigin>/oauth/callback?provider=discord`).
|
||||
|
||||
### Client-side wiring
|
||||
|
||||
7. Create `useAuth.js` as a module-level singleton composable under `src/client/src/composables/` using the reference template at `resources/templates/discord-oauth-vue3-vite/src/client/composables/useAuth.js`. The singleton exposes `user`, `features`, `isLoading`, `isLoggedIn`, `checkSession()`, `login()`, `logout()`, and `setSession()`.
|
||||
8. Create `DiscordAuthWidget` as an organism under `src/client/src/components/organisms/` with a colocated SCSS file and a stories stub, using the reference templates at `resources/templates/discord-oauth-vue3-vite/src/client/components/organisms/`. Update the SCSS `@use` paths to match the target project's style foundation before placing. Both the `.vue` and `.scss` must exist; the stories stub must export `LoggedOut` and `LoggedIn`.
|
||||
9. Create `OAuthCallbackPage.vue` under `src/client/src/pages/` using the reference template at `resources/templates/discord-oauth-vue3-vite/src/client/pages/OAuthCallbackPage.vue`. Register it on the `/oauth/callback` route with no `meta.requiresAuth` guard.
|
||||
10. Add a `beforeEach` router guard: call `checkSession()` before any route with `meta.requiresAuth: true` and redirect to `/` if `isLoggedIn` is false. Mark protected routes with `meta: { requiresAuth: true }`.
|
||||
11. Add a Vite dev proxy entry for `/api/auth` pointing to `http://localhost:<AUTH_PORT>` in `vite.config.js`.
|
||||
|
||||
### Runtime and validation
|
||||
|
||||
12. Either run the auth server as its own Node process (add an `auth:dev` script: `node src/server/discord-oauth/server.js`) or mount it into an existing backend entrypoint.
|
||||
13. Validate the flow: start login, complete the callback, check the session endpoint, refresh the session, and log out. Confirm the allowlist rejects an unapproved Discord account.
|
||||
|
||||
## Outputs
|
||||
|
||||
**Server bundle** (scaffold script writes these):
|
||||
|
||||
- `src/server/discord-oauth/server.js`
|
||||
- `src/server/discord-oauth/config.js`
|
||||
- `src/server/discord-oauth/sessionStore.js`
|
||||
- `src/server/discord-oauth/allowlist.js`
|
||||
- `src/server/discord-oauth/providers/discord.js`
|
||||
- `src/server/discord-oauth/lib/oauth/pkce.js`
|
||||
- `src/server/discord-oauth/lib/oauth/providers.js`
|
||||
- `src/server/discord-oauth/clients.example.json`
|
||||
- `src/server/discord-oauth/README.md`
|
||||
|
||||
**Client files** (placed from reference templates; adapt paths per project):
|
||||
|
||||
- `src/client/src/composables/useAuth.js`
|
||||
- `src/client/src/components/organisms/DiscordAuthWidget.vue`
|
||||
- `src/client/src/components/organisms/DiscordAuthWidget.scss`
|
||||
- `src/client/src/components/organisms/DiscordAuthWidget.stories.js`
|
||||
- `src/client/src/pages/OAuthCallbackPage.vue`
|
||||
|
||||
## Do Not Use
|
||||
|
||||
- Do not use this workflow when the project does not have a Node-side runtime path for auth code under `src/server/`.
|
||||
- Do not use this workflow when the project uses a hosted auth provider or a managed backend where Discord auth should not live in the repo.
|
||||
- Do not store secrets in the generated files.
|
||||
|
||||
## Notes
|
||||
|
||||
- This workflow follows the proven pattern: origin-specific client config, PKCE, Discord code exchange, allowlist gating, refresh-token rotation, and cookie cleanup.
|
||||
- Client template files live in `resources/templates/discord-oauth-vue3-vite/src/client/` and are reference-only. Adapt component paths and SCSS `@use` imports to match the target project's conventions before placing them.
|
||||
- Projects using atomic design require colocated SCSS and a stories stub for every organism; the `DiscordAuthWidget` templates satisfy this by default.
|
||||
- Keep the generated bundle generic to Vue 3 + Vite so the same path can be reused in other apps.
|
||||
- If the project does not already have a server entrypoint, add an `auth:dev` script that runs `node src/server/discord-oauth/server.js`, then configure Vite to proxy `/api/auth` to that port.
|
||||
@@ -0,0 +1,22 @@
|
||||
# Environment Variables
|
||||
|
||||
Set these in the target app or in the app's local env files.
|
||||
|
||||
- `AUTH_PORT` - auth service port, default `8787`
|
||||
- `NODE_ENV` - enables stricter secret checks outside development
|
||||
- `JWT_SECRET` - signing secret for access tokens
|
||||
- `ACCESS_TOKEN_TTL` - access token lifetime, default `15m`
|
||||
- `REFRESH_TOKEN_TTL_DAYS` - refresh session lifetime, default `30`
|
||||
- `COOKIE_NAME` - refresh token cookie name, default `gopvp_refresh`
|
||||
- `COOKIE_SECURE` - set to `true` for HTTPS deployments
|
||||
- `COOKIE_SAME_SITE` - cookie same-site mode, default `lax`
|
||||
- `AUTH_CLIENTS_FILE` - optional path to a JSON client map
|
||||
- `AUTH_CLIENTS_JSON` - optional inline JSON client map
|
||||
- `FRONTEND_ORIGIN` - legacy single-origin fallback
|
||||
- `DISCORD_CLIENT_ID` - legacy single-origin fallback
|
||||
- `DISCORD_CLIENT_SECRET` - legacy single-origin fallback
|
||||
- `DISCORD_SCOPES` - legacy single-origin fallback, default `identify,email`
|
||||
- `ALLOWLIST_DISCORD_IDS` - legacy single-origin fallback, comma-separated Discord user IDs
|
||||
- `DEFAULT_FEATURE_KEYS` - feature flags granted to allowlisted users
|
||||
|
||||
Keep secrets out of committed files and copy them into local environment files instead.
|
||||
@@ -0,0 +1,14 @@
|
||||
# Implementation Checklist
|
||||
|
||||
1. Create the Discord application and add the callback URL used by the app.
|
||||
2. Generate the `src/server/discord-oauth/` bundle from the scaffold.
|
||||
3. Copy `clients.example.json` to `clients.json` and fill in credentials.
|
||||
4. Set `AUTH_PORT`, `JWT_SECRET`, and the other auth env vars locally.
|
||||
5. Wire the auth server: add an `auth:dev` script or mount it into an existing backend entrypoint.
|
||||
6. Create `useAuth.js` singleton composable from the reference template; adapt the import path.
|
||||
7. Create `DiscordAuthWidget` organism (`.vue`, `.scss`, `.stories.js`) from reference templates; update SCSS `@use` paths to match the target project's style foundation.
|
||||
8. Create `OAuthCallbackPage.vue` from the reference template; register it at `/oauth/callback` with no auth guard.
|
||||
9. Add `meta: { requiresAuth: true }` to protected routes and a `beforeEach` guard that calls `checkSession()` and redirects to `/` if the user is not logged in.
|
||||
10. Add Vite dev proxy: `/api/auth` → `http://localhost:<AUTH_PORT>`.
|
||||
11. Test login, callback, session persistence, session refresh, and logout.
|
||||
12. Confirm the allowlist rejects a Discord account that is not approved.
|
||||
Reference in New Issue
Block a user