extremely claude-assisted go game based on atproto! working on cleaning up and giving a more unique design, still has a bit of a slop vibe to it.
1#!/usr/bin/env node
2/**
3 * Script to generate a private key for OAuth JWT signing
4 * Run with: node --loader tsx scripts/generate-key.ts
5 * Or add to package.json: "setup:key": "tsx scripts/generate-key.ts"
6 */
7
8import { generateClientAssertionKey } from '@atcute/oauth-crypto';
9import { writeFileSync, readFileSync, existsSync } from 'fs';
10import { join } from 'path';
11import { randomUUID } from 'crypto';
12
13async function generateKey() {
14 console.log('Generating OAuth private key...');
15
16 // Generate EC key for client assertions (OAuth)
17 const jwk = await generateClientAssertionKey();
18
19 // Add a kid (key ID) if not present - required by atcute
20 if (!jwk.kid) {
21 jwk.kid = randomUUID();
22 }
23
24 const jwkString = JSON.stringify(jwk);
25
26 const envPath = join(process.cwd(), '.env');
27 const envLocalPath = join(process.cwd(), '.env.local');
28
29 // Read existing .env content
30 let envContent = '';
31 if (existsSync(envPath)) {
32 envContent = readFileSync(envPath, 'utf-8');
33 }
34
35 // Check if PRIVATE_KEY_JWK already exists in .env (uncommented)
36 const keyLineRegex = /^PRIVATE_KEY_JWK=\{/m;
37 if (keyLineRegex.test(envContent)) {
38 console.log('⚠️ PRIVATE_KEY_JWK already exists in .env');
39 console.log(' To regenerate, remove the existing line first or delete the value');
40 console.log(' Run: sed -i.bak \'/^PRIVATE_KEY_JWK=/d\' .env');
41 return;
42 }
43
44 // Add the key to .env
45 const keyLine = `\nPRIVATE_KEY_JWK=${jwkString}\n`;
46 writeFileSync(envPath, envContent + keyLine, 'utf-8');
47
48 console.log('✅ Private key generated and saved to .env');
49 console.log(' IMPORTANT: Keep this key secure and never commit it to version control!');
50 console.log(' Add .env to your .gitignore if not already present');
51
52 // Update .env.example with placeholder
53 const envExamplePath = join(process.cwd(), '.env.example');
54 if (existsSync(envExamplePath)) {
55 let exampleContent = readFileSync(envExamplePath, 'utf-8');
56 if (!exampleContent.includes('PRIVATE_KEY_JWK=')) {
57 exampleContent += '\nPRIVATE_KEY_JWK={"kty":"...generated by setup:key script..."}\n';
58 writeFileSync(envExamplePath, exampleContent, 'utf-8');
59 console.log('✅ Updated .env.example with placeholder');
60 }
61 }
62
63 console.log('\n📝 Next steps:');
64 console.log(' 1. Ensure PUBLIC_BASE_URL is set in .env');
65 console.log(' 2. For production, use HTTPS and update PUBLIC_BASE_URL');
66 console.log(' 3. Run your dev server: npm run dev');
67}
68
69generateKey().catch(err => {
70 console.error('Error generating key:', err);
71 process.exit(1);
72});