Files
firefrost-services/docs/code-bridge/requests/REQ-2026-04-15-subscriber-wiki-auth.md

3.0 KiB

REQ-2026-04-15-subscriber-wiki-auth

From: Chronicler #92
Date: 2026-04-15
Priority: HIGH
Status: PENDING
Linked Task: #138 — Subscriber Wiki Discord OAuth + Tier Access Control

Note from Michael

Wiki.js is already deployed at subscribers.firefrostgaming.com but has no auth or content. This wires up access control so tier-gated content actually works. Same pattern as everything else — Discord OAuth already exists, Stripe webhook already fires, just need to add Wiki.js group sync to the flow.

What Needs to Be Built

1. Wiki.js GraphQL API integration

Create src/services/wikijsSync.js:

// Wiki.js uses GraphQL API at https://subscribers.firefrostgaming.com/graphql
// Auth via API key (stored in .env as WIKIJS_API_KEY)

async function syncWikiUser(discordId, username, tierLevel)
// Creates user if not exists, updates group assignment if they do
// Group mapping:
//   tier_level 1 (Awakened)   → Wiki group: "Awakened"
//   tier_level 2 (Elemental)  → Wiki group: "Elemental"  
//   tier_level 3 (Knight)     → Wiki group: "Knight"
//   tier_level 4 (Master)     → Wiki group: "Master"
//   tier_level 5 (Legend)     → Wiki group: "Legend"
//   tier_level 6 (Sovereign)  → Wiki group: "Sovereign"

2. Hook into existing Stripe webhook flow

In src/routes/stripe.js, after the existing Discord role sync and LuckPerms sync, add:

// Sync Wiki.js user group (non-blocking, silent-fail)
wikijsSync.syncWikiUser(discordId, username, tierLevel)
  .catch(err => console.error('[WikiSync] Failed:', err.message));

3. Hook into lifecycle handlers (cancellation/grace)

When a subscriber cancels or enters grace period, demote their Wiki.js group to Awakened — same as Discord role demotion.

4. Add WIKIJS_API_KEY to .env.example

Document the new env var.

Wiki.js GraphQL Mutations Needed

# Create user
mutation CreateUser($email: String!, $name: String!, $groups: [Int!]!) {
  users {
    create(email: $email, name: $name, passwordRaw: "", providerKey: "discord", groups: $groups) {
      responseResult { succeeded message }
    }
  }
}

# Update user groups  
mutation UpdateUser($id: Int!, $groups: [Int!]!) {
  users {
    update(id: $id, groups: $groups) {
      responseResult { succeeded message }
    }
  }
}

# Search user by email
query FindUser($email: String!) {
  users {
    search(query: $email) { id email }
  }
}

Notes

  • Wiki.js user email = discordId@firefrost.local (unique, internal)
  • Wiki.js groups must be pre-created manually (Awakened, Elemental, Knight, Master, Legend, Sovereign) — Michael does this in Wiki.js admin panel before deploy
  • Silent-fail pattern — never let wiki sync break the Stripe webhook
  • Log successes and failures to console for debugging
  • WIKIJS_API_KEY generated in Wiki.js admin → API Access

Files to Touch

  • New: src/services/wikijsSync.js
  • Modify: src/routes/stripe.js
  • Modify: src/routes/stripe.js lifecycle handlers (cancellation/grace)
  • Modify: .env.example (add WIKIJS_API_KEY)