OAuth Implementation - Wiz-DevTech/grok_kcc GitHub Wiki
Secure Setup Confirmation & Sample OAuth Implementation
Thanks for sharing—I've noted the Client ID (M539PU4124AA4ZJ2W1P0YO8HVR1ZPUBH) for reference. Critical Security Note: Never share or commit the Client Secret (IN83KN2ZF7NAPSF27QG0800FA1P0XFAP0EIFE9C47TNRR9UU8SK3PSNY2BPRLMAUY) to public repos, logs, or chats again—treat it like a password. Store it in env vars (e.g., .env file) or a secrets manager (Vault). If compromised, regenerate it in ClickUp's Apps settings ASAP.
With these creds, your "Saas-DID Foundation Hub" app is ready for production-grade integrations (e.g., GitHub Actions for task updates or bots for AI summaries). Below, I'll provide a plug-and-play Node.js sample for the full OAuth flow: authorizing users, fetching tokens, and making a simple API call (e.g., list your Workspace tasks). This ties directly into our project—e.g., use it in a GitHub Action to sync Phase 1 audit tasks.
Prerequisites
- Node.js 18+ installed.
- Create a
.envfile in your project root:CLICKUP_CLIENT_ID=M539PU4124AA4ZJ2W1P0YO8HVR1ZPUBH CLICKUP_CLIENT_SECRET=IN83KN2ZF7NAPSF27QG0800FA1P0XFAP0EIFE9C47TNRR9UU8SK3PSNY2BPRLMAUY REDIRECT_URI=http://localhost:3000/callback # Matches your app's registered URL - Run
npm init -y && npm i express dotenv axios qsfor deps.
Sample Node.js OAuth Server (auth.js)
This sets up a mini Express server:
- Redirects to ClickUp for auth.
- Handles callback, exchanges code for token.
- Uses token to fetch tasks (e.g., from your "SaaS-DID Foundation Hub" Workspace).
require('dotenv').config();
const express = require('express');
const axios = require('axios');
const qs = require('qs');
const app = express();
const PORT = 3000;
const CLIENT_ID = process.env.CLICKUP_CLIENT_ID;
const CLIENT_SECRET = process.env.CLICKUP_CLIENT_SECRET;
const REDIRECT_URI = process.env.REDIRECT_URI;
// Step 1: Auth endpoint (hit /auth to start login)
app.get('/auth', (req, res) => {
const authUrl = `https://auth.clickup.com/oauth/authorize?${qs.stringify({
client_id: CLIENT_ID,
redirect_uri: REDIRECT_URI,
response_type: 'code',
state: 'state_xyz' // Anti-CSRF; customize
})}`;
res.redirect(authUrl);
});
// Step 2: Callback handler
app.get('/callback', async (req, res) => {
const { code, state, error } = req.query;
if (error || state !== 'state_xyz') {
return res.status(400).send('Auth failed');
}
try {
// Exchange code for tokens
const tokenResponse = await axios.post('https://auth.clickup.com/api/oauth/token', qs.stringify({
grant_type: 'authorization_code',
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET,
code,
redirect_uri: REDIRECT_URI
}), {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
const { access_token, refresh_token } = tokenResponse.data;
console.log('Tokens:', { access_token, refresh_token }); // Store securely (e.g., DB/session)
// Step 3: Example API call - Fetch tasks from your Workspace (replace TEAM_ID with yours from /api/v2/team)
const tasksResponse = await axios.get('https://api.clickup.com/api/v2/team/TEAM_ID/task', { // Get TEAM_ID via GET /api/v2/team
headers: { Authorization: access_token }
});
console.log('Sample Tasks:', tasksResponse.data); // e.g., List Phase 1 tasks
res.send(`Success! Tokens acquired. Check console for tasks. <a href="/auth">Re-auth</a>`);
} catch (err) {
console.error('Token exchange failed:', err.response?.data);
res.status(500).send('Token fetch error');
}
});
app.listen(PORT, () => {
console.log(`Server running at http://localhost:${PORT}. Hit /auth to start.`);
});
How to Run & Test
- Save as
auth.js, thennode auth.js. - Visit
http://localhost:3000/auth→ ClickUp login → Redirect back. - Console logs tokens + sample tasks. If no tasks, first create the Workspace/Space via ClickUp UI.
- Token Refresh: When access_token expires (2 hours), use refresh_token:
// Add to your code const refreshResponse = await axios.post('https://auth.clickup.com/api/oauth/token', qs.stringify({ grant_type: 'refresh_token', client_id: CLIENT_ID, client_secret: CLIENT_SECRET, refresh_token }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } });
Project Integration Examples
- GitHub Action for Sync: Update the YAML from earlier:
- name: Refresh & Update Task run: node update-task.js # Script using access_token to PUT /task/{id} with phase status env: CLICKUP_ACCESS_TOKEN: ${{ secrets.CLICKUP_TOKEN }} # Store tokens in GitHub Secrets - Bot/AI Flow: In n8n/Zapier, use this token to call
POST /list/{id}/taskfor AI-generated subtasks (e.g., from OpenAI: "Create DID audit checklist"). - Scale Tip: For team use, store tokens per-user in a DB (e.g., PostgreSQL with your SaaS multi-tenancy).
This gets your automations live in minutes—e.g., auto-update Phase 2 refactor tasks on GitHub merge. Tested the flow mentally against ClickUp docs; if you hit snags (e.g., TEAM_ID), share the error, and I'll debug. Next up: Full GitHub sync script or n8n workflow?