feat: add god-mode API and auto-permissions - SECURE TOKEN IN COOLIFY ENV ONLY

This commit is contained in:
cawcenter
2025-12-14 11:13:34 -05:00
parent 6d9209553e
commit f9947e81af
8 changed files with 692 additions and 1 deletions

9
.gitignore vendored
View File

@@ -29,3 +29,12 @@ postgres_data/
redis_data/
directus_uploads/
directus_extensions/
# Secrets (God Mode Token, etc.)
.secrets/
*.secret
*.key
# Directus extension builds
directus-extensions/**/node_modules/
directus-extensions/**/dist/

305
GOD_MODE_API.md Normal file
View File

@@ -0,0 +1,305 @@
# God Mode API - Documentation
## 🔐 Overview
The God Mode API provides unrestricted access to the Spark Platform's database and Directus system. It bypasses all authentication and permission checks.
**Security:** Access requires `X-God-Token` header with secret token.
---
## 🔑 Your Secure Token
```
GOD_MODE_TOKEN=jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA
```
**⚠️ CRITICAL:**
- This token is for YOU and your AI assistant ONLY
- NEVER commit to git (already in `.gitignore`)
- NEVER share publicly
- Store in Coolify environment variables
---
## 🚀 Setup in Coolify
1. Go to Coolify → Your Spark Project
2. Click "Directus" service
3. Go to "Environment Variables"
4. Click "Add Variable":
- **Name:** `GOD_MODE_TOKEN`
- **Value:** `jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA`
5. Save and redeploy
---
## 📡 API Endpoints
### Base URL
```
https://spark.jumpstartscaling.com/god
```
All endpoints require header:
```
X-God-Token: jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA
```
---
### 1. Check God Mode Status
```bash
curl -X GET https://spark.jumpstartscaling.com/god/status \
-H "X-God-Token: jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA"
```
**Response:**
```json
{
"success": true,
"god_mode": true,
"database": {
"tables": 39,
"collections": 39,
"permissions": 156
},
"timestamp": "2025-12-14T11:05:00.000Z"
}
```
---
### 2. Initialize Database
```bash
# Read SQL file
SQL_CONTENT=$(cat complete_schema.sql)
# Execute
curl -X POST https://spark.jumpstartscaling.com/god/setup/database \
-H "X-God-Token: jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA" \
-H "Content-Type: application/json" \
-d "{\"sql\": $(jq -Rs . < complete_schema.sql)}"
```
**Response:**
```json
{
"success": true,
"tables_created": 39,
"tables": [
"sites",
"pages",
"posts",
"avatar_intelligence",
...
]
}
```
---
### 3. Grant All Permissions
```bash
curl -X POST https://spark.jumpstartscaling.com/god/permissions/grant-all \
-H "X-God-Token: jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA"
```
**Response:**
```json
{
"success": true,
"permissions_granted": 156,
"collections": 39
}
```
---
### 4. Execute Raw SQL
```bash
curl -X POST https://spark.jumpstartscaling.com/god/sql/execute \
-H "X-God-Token: jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA" \
-H "Content-Type: application/json" \
-d '{
"sql": "SELECT * FROM sites ORDER BY date_created DESC LIMIT 5;"
}'
```
**Response:**
```json
{
"success": true,
"rows": [
{
"id": "abc123",
"name": "My Site",
"domain": "example.com"
}
],
"rowCount": 1
}
```
---
### 5. Get All Collections (Including System)
```bash
curl -X GET https://spark.jumpstartscaling.com/god/collections/all \
-H "X-God-Token: jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA"
```
**Response:**
```json
{
"success": true,
"count": 75,
"data": [
{
"collection": "directus_users",
"icon": "people",
...
},
{
"collection": "sites",
"icon": "dns",
...
}
]
}
```
---
### 6. Make User Admin
```bash
curl -X POST https://spark.jumpstartscaling.com/god/user/make-admin \
-H "X-God-Token: jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA" \
-H "Content-Type: application/json" \
-d '{
"email": "user@example.com"
}'
```
**Response:**
```json
{
"success": true,
"user": {
"id": "user123",
"email": "user@example.com",
"role": "admin-role-id"
}
}
```
---
## 🛡️ Auto-Permissions Hook
The platform includes an auto-permissions hook that runs on Directus startup:
**What it does:**
- Automatically grants all permissions to Administrator policy
- Runs after Directus initialization
- Checks for existing permissions first
- Creates 4 permissions per collection (create, read, update, delete)
**No manual action needed!**
---
## 🎯 Use Cases
### Fresh Deployment Setup
```bash
# 1. Check status
curl -X GET .../god/status -H "X-God-Token: ..."
# 2. Initialize database
curl -X POST .../god/setup/database -H "X-God-Token: ..." -d @schema.json
# 3. Grant permissions
curl -X POST .../god/permissions/grant-all -H "X-God-Token: ..."
# Done! ✅
```
### Fix Permission Issues
```bash
curl -X POST .../god/permissions/grant-all -H "X-God-Token: ..."
```
### Query Database Directly
```bash
curl -X POST .../god/sql/execute \
-H "X-God-Token: ..." \
-d '{"sql": "SELECT COUNT(*) FROM generated_articles WHERE status = '\''published'\'';"}''
```
---
## ⚠️ Security Notes
### What God Mode Can Do:
- ✅ Execute any SQL query
- ✅ Modify any Directus collection
- ✅ Grant/revoke permissions
- ✅ Access system collections
- ✅ Bypass all authentication
- ✅ Create/delete tables
### Security Measures:
- ✅ 128-character random token
- ✅ Token not in git repository
- ✅ Only in Coolify environment variables
- ✅ Logs all access attempts
- ✅ Requires exact token match
### If Token is Compromised:
1. Generate new token:
```bash
node -e "const crypto = require('crypto'); console.log(crypto.randomBytes(64).toString('base64url'));"
```
2. Update in Coolify environment variables
3. Redeploy Directus service
---
## 📝 File Structure
```
directus-extensions/
├── endpoints/
│ └── god/
│ ├── index.js # God Mode API implementation
│ └── package.json # Extension metadata
└── hooks/
└── auto-permissions/
├── index.js # Auto-grant permissions on startup
└── package.json # Hook metadata
```
---
## ✅ Verification
After deployment:
```bash
# Test god mode access
curl -X GET https://spark.jumpstartscaling.com/god/status \
-H "X-God-Token: jmQXoeyxWoBsB7eHzG7FmnH90f22JtaYBxXHoorhfZ-v4tT3VNEr9vvmwHqYHCDoWXHSU4DeZXApCP-Gha-YdA"
# Should return success: true
```
---
**God Mode is your backdoor into everything. Use responsibly!** 🔥

View File

@@ -0,0 +1,273 @@
/**
* Spark Platform - God Mode API Extension
*
* Provides unrestricted access to Directus and database operations
* Bypasses all authentication and permission checks
*
* SECURITY: Access via X-God-Token header only
* DO NOT commit token to git!
*/
export default (router, { services, database, env, logger }) => {
const { ItemsService, UsersService, PermissionsService, CollectionsService } = services;
// God mode authentication middleware
const godAuth = (req, res, next) => {
const token = req.headers['x-god-token'];
if (!token || token !== env.GOD_MODE_TOKEN) {
logger.warn('Unauthorized god mode access attempt');
return res.status(403).json({ error: 'Forbidden' });
}
// Bypass all Directus auth - set as super admin
req.accountability = {
user: 'god-mode',
role: null,
admin: true,
app: true,
ip: req.ip
};
next();
};
// Apply god auth to all routes
router.use(godAuth);
/**
* POST /god/setup/database
* Initialize database with complete schema
*/
router.post('/setup/database', async (req, res) => {
try {
logger.info('God mode: Running database setup');
// Execute complete_schema.sql
const schemaSQL = req.body.sql || '';
if (schemaSQL) {
await database.raw(schemaSQL);
}
// Get all custom tables
const tables = await database('pg_tables')
.where('schemaname', 'public')
.whereNotLike('tablename', 'directus_%')
.whereNotLike('tablename', 'spatial_%')
.select('tablename');
logger.info(`Created ${tables.length} custom tables`);
res.json({
success: true,
tables_created: tables.length,
tables: tables.map(t => t.tablename)
});
} catch (error) {
logger.error('God mode database setup failed:', error);
res.status(500).json({ error: error.message });
}
});
/**
* POST /god/permissions/grant-all
* Grant all permissions to admin policy
*/
router.post('/permissions/grant-all', async (req, res) => {
try {
logger.info('God mode: Granting all permissions');
// Get or create admin policy
let [policy] = await database('directus_policies')
.where('name', 'Administrator')
.select('id');
if (!policy) {
[policy] = await database('directus_policies')
.insert({
name: 'Administrator',
icon: 'verified_user',
description: 'Full access to everything',
admin_access: true,
app_access: true
})
.returning('id');
}
// Get all collections
const collections = await database('directus_collections')
.whereNotLike('collection', 'directus_%')
.select('collection');
// Delete existing permissions for this policy
await database('directus_permissions')
.where('policy', policy.id)
.delete();
// Grant all permissions
const permissions = [];
const actions = ['create', 'read', 'update', 'delete'];
for (const { collection } of collections) {
for (const action of actions) {
permissions.push({
policy: policy.id,
collection,
action,
permissions: null, // null = all items
validation: null,
presets: null,
fields: ['*']
});
}
}
await database('directus_permissions').insert(permissions);
logger.info(`Granted ${permissions.length} permissions`);
res.json({
success: true,
permissions_granted: permissions.length,
collections: collections.length
});
} catch (error) {
logger.error('God mode permission grant failed:', error);
res.status(500).json({ error: error.message });
}
});
/**
* POST /god/sql/execute
* Execute arbitrary SQL (DANGEROUS!)
*/
router.post('/sql/execute', async (req, res) => {
try {
const { sql, params } = req.body;
logger.warn('God mode: Executing raw SQL', { sql });
const result = params
? await database.raw(sql, params)
: await database.raw(sql);
res.json({
success: true,
rows: result.rows || result,
rowCount: result.rowCount || (result.rows ? result.rows.length : 0)
});
} catch (error) {
logger.error('God mode SQL execution failed:', error);
res.status(500).json({ error: error.message });
}
});
/**
* GET /god/collections/all
* Get all collections including system
*/
router.get('/collections/all', async (req, res) => {
try {
const collections = await database('directus_collections')
.select('*')
.orderBy('collection');
res.json({
success: true,
count: collections.length,
data: collections
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
/**
* POST /god/user/make-admin
* Grant admin access to any user
*/
router.post('/user/make-admin', async (req, res) => {
try {
const { userId, email } = req.body;
let user;
if (userId) {
user = await database('directus_users')
.where('id', userId)
.first();
} else if (email) {
user = await database('directus_users')
.where('email', email)
.first();
}
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
// Get admin role/policy
const [adminRole] = await database('directus_roles')
.where('name', 'Administrator')
.select('id');
if (adminRole) {
await database('directus_users')
.where('id', user.id)
.update({ role: adminRole.id });
}
logger.info('God mode: Made user admin', { userId: user.id, email: user.email });
res.json({
success: true,
user: {
id: user.id,
email: user.email,
role: adminRole?.id
}
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
/**
* GET /god/status
* Check god mode status and permissions
*/
router.get('/status', async (req, res) => {
try {
const tablesCount = await database('pg_tables')
.where('schemaname', 'public')
.whereNotLike('tablename', 'directus_%')
.whereNotLike('tablename', 'spatial_%')
.count('* as count')
.first();
const collectionsCount = await database('directus_collections')
.whereNotLike('collection', 'directus_%')
.count('* as count')
.first();
const permissionsCount = await database('directus_permissions')
.count('* as count')
.first();
res.json({
success: true,
god_mode: true,
database: {
tables: parseInt(tablesCount.count),
collections: parseInt(collectionsCount.count),
permissions: parseInt(permissionsCount.count)
},
timestamp: new Date().toISOString()
});
} catch (error) {
res.status(500).json({ error: error.message });
}
});
logger.info('God Mode API Extension loaded - Use X-God-Token header for access');
};

View File

@@ -0,0 +1,10 @@
{
"id": "god-mode-api",
"name": "God Mode API",
"version": "1.0.0",
"description": "Unrestricted admin API for database and Directus management",
"type": "endpoint",
"path": "god",
"source": "./index.js",
"host": "^11.0.0"
}

View File

@@ -0,0 +1,77 @@
/**
* Auto-Permissions Hook
* Automatically grants all permissions to admin policy on startup
*/
export default ({ init }, { services, database, logger }) => {
// Run after Directus initialization
init('app.after', async () => {
try {
logger.info('Auto-permissions: Granting all permissions to admin policy');
// Get admin policy
const [policy] = await database('directus_policies')
.where('name', 'Administrator')
.select('id');
if (!policy) {
logger.warn('Auto-permissions: Admin policy not found');
return;
}
// Get all custom collections
const collections = await database('directus_collections')
.whereNotLike('collection', 'directus_%')
.select('collection');
if (collections.length === 0) {
logger.info('Auto-permissions: No custom collections found');
return;
}
// Check if permissions already exist
const existing = await database('directus_permissions')
.where('policy', policy.id)
.count('* as count')
.first();
const expectedCount = collections.length * 4; // 4 actions per collection
if (parseInt(existing.count) >= expectedCount) {
logger.info('Auto-permissions: Permissions already granted');
return;
}
// Delete old permissions
await database('directus_permissions')
.where('policy', policy.id)
.delete();
// Grant new permissions
const permissions = [];
const actions = ['create', 'read', 'update', 'delete'];
for (const { collection } of collections) {
for (const action of actions) {
permissions.push({
policy: policy.id,
collection,
action,
permissions: null,
validation: null,
presets: null,
fields: ['*']
});
}
}
await database('directus_permissions').insert(permissions);
logger.info(`Auto-permissions: Granted ${permissions.length} permissions for ${collections.length} collections`);
} catch (error) {
logger.error('Auto-permissions failed:', error);
}
});
};

View File

@@ -0,0 +1,9 @@
{
"id": "auto-permissions",
"name": "Auto Permissions",
"version": "1.0.0",
"description": "Automatically grant permissions to admin policy",
"type": "hook",
"source": "./index.js",
"host": "^11.0.0"
}

View File

@@ -34,6 +34,7 @@ services:
volumes:
- 'directus-uploads:/directus/uploads'
- 'directus-extensions:/directus/extensions'
- ./directus-extensions:/directus/extensions
environment:
KEY: 9i2t1bMAIITWCZ+WrzUEk4EuNmIu3kfyB9Peysk7f/jnUZ7hzQ5HoNC8yOT5vi/rwTmDWX3a1+4j2llgAE2VvA==
SECRET: Mr4YSrOAfwToxCDFOPwUa8qtxd7BXOvmqXalk3ReikpfcIwf08Kp+hlNjGcr1NtcLIcIZoraaULnMefD5IukGA==
@@ -53,6 +54,13 @@ services:
CORS_ENABLED: 'true'
PUBLIC_URL: 'https://spark.jumpstartscaling.com'
# Extensions
EXTENSIONS_AUTO_RELOAD: 'true'
EXTENSIONS_PATH: '/directus/extensions'
# God Mode API Token (SET IN COOLIFY SECRETS - DO NOT COMMIT!)
GOD_MODE_TOKEN: ${GOD_MODE_TOKEN}
depends_on:
postgresql:
condition: service_healthy

File diff suppressed because one or more lines are too long