06 - Admin-Panel
Relevant source files
Purpose and ScopeLink copied!
The Admin Panel is a password-protected web interface that enables the system owner to generate GitHub App installation access tokens for accessing customer repositories. This panel serves as the manual intervention point in the repository access workflow, allowing the owner to retrieve customer code after payment and GitHub App installation have been completed.
This document covers the admin panel UI (app/admin/page.tsx
), the token generation API (app/api/admin/generate-token/route.ts
), and the manual workflow for accessing customer repositories. For information about the automated repository cloning scripts that can also use these tokens, see Automation System. For details on how customers connect their GitHub accounts, see OAuth Callback Handler.
Admin Panel ArchitectureLink copied!
The admin panel consists of two primary components: a client-side React interface and a server-side token generation API.
Component StructureLink copied!
Sources: app/admin/page.tsx L1-L363
app/api/admin/generate-token/route.ts L1-L57
State ManagementLink copied!
The admin panel maintains authentication and token data in React state without any backend session storage:
| State Variable | Type | Purpose |
|---|---|---|
password | string | User-entered admin password |
isAuthenticated | boolean | Authentication status (persisted to localStorage) |
installationId | string | GitHub App installation ID input |
customerEmail | string | Optional customer email for repo naming |
loading | boolean | Token generation loading state |
tokenData | object | Generated token, expiry, repositories, and user details |
error | string | Error messages from API calls |
Sources: app/admin/page.tsx L13-L28
Authentication FlowLink copied!
Password-Based AuthenticationLink copied!
The admin panel uses a simple password-based authentication mechanism without sessions or JWTs.
Sources: app/admin/page.tsx L30-L48
Security ConsiderationsLink copied!
The authentication mechanism has the following characteristics:
| Aspect | Implementation | Security Level |
|---|---|---|
| Password Storage | ADMIN_PASSWORD environment variable | ✓ Server-side only |
| Client Exposure | NEXT_PUBLIC_ADMIN_PASSWORD NOT used | ✓ Password not in client bundle |
| Session Persistence | localStorage flag admin_authenticated | ⚠️ Client-side only, no server validation |
| Password Transmission | Sent with each token generation request | ✓ HTTPS-encrypted |
| Rate Limiting | None implemented | ⚠️ Vulnerable to brute force |
Note: The NEXT_PUBLIC_ADMIN_PASSWORD environment variable mentioned in the high-level diagrams is not actually used in the codebase. The actual implementation uses server-side-only ADMIN_PASSWORD verification.
Sources: app/api/admin/generate-token/route.ts L8-L15
Token Generation WorkflowLink copied!
Installation ID InputLink copied!
The owner must manually locate the installation_id from system logs or GitHub webhooks before using the admin panel. The workflow relies on correlation between Stripe payment data and Vercel logs.
Sources: app/admin/page.tsx L165-L204
Token Generation API RequestLink copied!
The token generation process involves three GitHub API calls executed server-side:
Sources: app/api/admin/generate-token/route.ts L4-L57
API Request and Response FormatLink copied!
Request Body:
{ "installationId": "12345678", "password": "admin_password_value"}
Successful Response (200):
{ "token": "ghs_xxxxxxxxxxxx", "expiresAt": "2024-01-15T12:00:00Z", "repositories": [ { "id": 123456, "name": "customer-repo", "full_name": "customer/customer-repo", "description": "Repository description", "private": true, "html_url": "https://github.com/customer/customer-repo" } ], "user": { "username": "customer", "email": "customer@example.com", "name": "Customer Name" }}
Error Response (401):
{ "error": "Unauthorized"}
Error Response (400):
{ "error": "Installation ID is required"}
Sources: app/api/admin/generate-token/route.ts L6-L44
UI Features and ComponentsLink copied!
Token Display InterfaceLink copied!
When a token is successfully generated, the admin panel displays three main sections:
Sources: app/admin/page.tsx L217-L360
Repository Naming ConventionLink copied!
The admin panel implements a repository naming convention for creating private mirrors in the owner's account:
| Input | Processing | Output Repository Name |
|---|---|---|
Customer Email: user@example.com | Replace @ with _, . with _, lowercase | user_example_com-repo-name |
| Customer Email: (empty) | Use GitHub username from API | githubuser-repo-name |
| Customer Email: (not provided) | Use GitHub email from API | email_domain_com-repo-name |
The formatRepoName() function at app/admin/page.tsx L91-L98
implements this logic:
const formatRepoName = (repoName: string) => { const email = customerEmail || tokenData?.user?.email || tokenData?.user?.username if (!email) return repoName const emailPart = email.replace(/@/g, "_").replace(/\./g, "_").toLowerCase() return `${emailPart}-${repoName}`}
Sources: app/admin/page.tsx L91-L98
Copy-to-Clipboard FunctionalityLink copied!
The admin panel provides one-click copying for multiple use cases:
| Button Label | Copied Content | Purpose |
|---|---|---|
| Copy (token field) | Raw installation access token | Manual git operations |
| Clone | git clone https://x-access-token:{token}@github.com/{full_name}.git | Clone customer repository |
| Clone to Personal | Multi-line bash script | Clone, re-init, push to klaudioz/{email-reponame} |
| URL | https://github.com/{full_name} | Open in browser |
The "Clone to Personal" command generates a complete bash pipeline:
git clone https://x-access-token:{token}@github.com/{customer/repo}.git temp-repo && \cd temp-repo && \rm -rf .git && \git init && \git add . && \git commit -m "Initial commit" && \gh repo create klaudioz/{customer_email_com-repo} --private --source=. --push
Sources: app/admin/page.tsx L87-L89
Manual Repository Access WorkflowLink copied!
Complete Owner WorkflowLink copied!
The owner's manual process for accessing customer repositories follows these steps:
Sources: CLAUDE.md L180-L184
Token Lifespan and SecurityLink copied!
Installation access tokens generated by the admin panel have specific security constraints:
| Property | Value | Enforced By |
|---|---|---|
| Maximum Lifespan | 1 hour | GitHub API |
| Permissions | Read-only: Contents, Metadata | GitHub App configuration |
| Scope | Only repositories selected during installation | Customer choice during OAuth |
| Revocation | Automatic after expiry | GitHub |
| Regeneration | Owner must use admin panel again | No refresh token mechanism |
The short lifespan minimizes security exposure if a token is leaked. The owner must generate a new token for each access session.
Sources: app/admin/page.tsx L229
Error HandlingLink copied!
The admin panel handles several error conditions:
| Error Condition | HTTP Status | Error Message | User Action |
|---|---|---|---|
| Invalid password | 401 | "Unauthorized" | Re-enter password |
| Missing installation_id | 400 | "Installation ID is required" | Enter installation_id |
| Invalid installation_id | 500 | GitHub API error message | Verify installation_id in logs |
| Token generation failure | 500 | "Failed to generate token" | Check GitHub App credentials |
| Network failure | N/A | Caught in try/catch | Retry request |
Sources: app/api/admin/generate-token/route.ts L45-L56
Integration with Automation ScriptsLink copied!
While the admin panel provides a manual interface for token generation, the same /api/admin/generate-token endpoint is also used by automated scripts:
The automation scripts extract the installation_id from ntfy notifications and call the same API endpoint with the ADMIN_PASSWORD to generate tokens programmatically. For details on the automation pipeline, see Repository Cloning Automation.
Sources: app/api/admin/generate-token/route.ts L1-L57
Session ManagementLink copied!
localStorage PersistenceLink copied!
The admin panel uses browser localStorage for session persistence:
// On successful authenticationlocalStorage.setItem("admin_authenticated", "true")// On page loaduseEffect(() => { const authState = localStorage.getItem("admin_authenticated") if (authState === "true") { setIsAuthenticated(true) }}, [])// On logoutlocalStorage.removeItem("admin_authenticated")
Characteristics:
- No server-side session validation
- Persists across browser tabs
- Cleared on logout or browser data clear
- No automatic expiry mechanism
Sources: app/admin/page.tsx L30-L36
Logout FunctionalityLink copied!
The logout handler at app/admin/page.tsx L50-L55
performs four actions:
- Sets
isAuthenticatedtofalse(hides admin UI) - Removes
admin_authenticatedfrom localStorage - Clears
tokenDatastate (removes sensitive token data) - Clears
installationIdinput field
This ensures that sensitive data is not left in memory or browser storage after the owner finishes their session.
Sources: app/admin/page.tsx L50-L55
DependenciesLink copied!
The admin panel relies on the following external components:
| Component | Purpose | Location |
|---|---|---|
| shadcn/ui components | UI primitives (Button, Input, Card, Alert) | components/ui/* |
| Lucide React icons | Visual icons (Copy, Key, Lock, GitBranch, LogOut) | lucide-react package |
verifyPassword action | Server-side password verification | app/admin/actions.ts |
lib/github-app.ts functions | GitHub App JWT and token generation | lib/github-app.ts |
| Environment variables | ADMIN_PASSWORD, GITHUB_APP_ID, GITHUB_PRIVATE_KEY | Vercel environment |
Sources: app/admin/page.tsx L1-L10
app/api/admin/generate-token/route.ts L2
Refresh this wiki
Last indexed: 23 November 2025 (922b35)
On this page
- Admin Panel
- Purpose and Scope
- Admin Panel Architecture
- Component Structure
- State Management
- Authentication Flow
- Password-Based Authentication
- Security Considerations
- Token Generation Workflow
- Installation ID Input
- Token Generation API Request
- API Request and Response Format
- UI Features and Components
- Token Display Interface
- Repository Naming Convention
- Copy-to-Clipboard Functionality
- Manual Repository Access Workflow
- Complete Owner Workflow
- Token Lifespan and Security
- Error Handling
- Integration with Automation Scripts
- Session Management
- localStorage Persistence
- Logout Functionality
- Dependencies
Ask Devin about godeep.wiki-jb
Syntax error in text
mermaid version 11.4.1