feat: add cmd openid-conf

This commit is contained in:
monoid 2025-04-10 22:03:11 +09:00
parent 21a2b5aa26
commit fc9035148c

69
app.ts
View file

@ -14,46 +14,46 @@ const CREDENTIALS_FILE = `${homedir()}/.oauth2cli-forgejo`;
async function main() { async function main() {
const tokenApi = new TokenApi(URL_BASE, TOKEN_NAME); const tokenApi = new TokenApi(URL_BASE, TOKEN_NAME);
const credentialManager = new CredentialManager(CREDENTIALS_FILE, TOKEN_NAME); const credentialManager = new CredentialManager(CREDENTIALS_FILE, TOKEN_NAME);
try { try {
await new Command() await new Command()
.name("forgejo-oauth2cli") .name("forgejo-oauth2cli")
.version("0.1.0") .version("0.1.0")
.description("Interactive client credentials generator for Forgejo.") .description("Interactive client credentials generator for Forgejo.")
.command("login", "Authenticate with Forgejo interactively") .command("login", "Authenticate with Forgejo interactively")
.action(async() => { .action(async () => {
const username = await prompt("Enter your username: "); const username = await prompt("Enter your username: ");
if (!username) { if (!username) {
console.error("Username is required."); console.error("Username is required.");
return; return;
} }
const secret = await Secret.prompt("Enter your secret: "); const secret = await Secret.prompt("Enter your secret: ");
if (!secret) { if (!secret) {
console.error("Secret is required."); console.error("Secret is required.");
return; return;
} }
// Check for existing tokens // Check for existing tokens
const tokens = await tokenApi.listTokens(username, secret); const tokens = await tokenApi.listTokens(username, secret);
if (!tokens) { if (!tokens) {
return; return;
} }
// Delete existing token if found // Delete existing token if found
const existingToken = tokens.find(t => t.name === TOKEN_NAME); const existingToken = tokens.find(t => t.name === TOKEN_NAME);
if (existingToken) { if (existingToken) {
console.log("Existing token found, replacing it..."); console.log("Existing token found, replacing it...");
await tokenApi.deleteToken(username, secret, existingToken.id); await tokenApi.deleteToken(username, secret, existingToken.id);
} }
// Create new token // Create new token
console.log("Creating new token..."); console.log("Creating new token...");
const token = await tokenApi.createToken(username, secret); const token = await tokenApi.createToken(username, secret);
if (!token) { if (!token) {
return; return;
} }
// Store credentials // Store credentials
await credentialManager.storeCredentials(username, token.sha1); await credentialManager.storeCredentials(username, token.sha1);
console.log("Login successful! Credentials stored securely."); console.log("Login successful! Credentials stored securely.");
@ -65,25 +65,25 @@ async function main() {
console.error("Username is required."); console.error("Username is required.");
return; return;
} }
const secret = await Secret.prompt("Enter your secret: "); const secret = await Secret.prompt("Enter your secret: ");
if (!secret) { if (!secret) {
console.error("Secret is required."); console.error("Secret is required.");
return; return;
} }
// Find and delete token // Find and delete token
const tokens = await tokenApi.listTokens(username, secret); const tokens = await tokenApi.listTokens(username, secret);
if (!tokens) { if (!tokens) {
return; return;
} }
const existingToken = tokens.find(t => t.name === TOKEN_NAME); const existingToken = tokens.find(t => t.name === TOKEN_NAME);
if (existingToken) { if (existingToken) {
await tokenApi.deleteToken(username, secret, existingToken.id); await tokenApi.deleteToken(username, secret, existingToken.id);
console.log("Token deleted from Forgejo."); console.log("Token deleted from Forgejo.");
} }
// Clear stored credentials // Clear stored credentials
await credentialManager.clearCredentials(username); await credentialManager.clearCredentials(username);
console.log("Logout successful! Credentials removed."); console.log("Logout successful! Credentials removed.");
@ -93,12 +93,12 @@ async function main() {
.action(async (opt) => { .action(async (opt) => {
const credentials = await credentialManager.getCredentials(); const credentials = await credentialManager.getCredentials();
if (!credentials) return; if (!credentials) return;
// Create OAuth2Api with token // Create OAuth2Api with token
const oauth2Api = new OAuth2Api(URL_BASE, credentials.token); const oauth2Api = new OAuth2Api(URL_BASE, credentials.token);
const apps = await oauth2Api.getOauth2Applications(); const apps = await oauth2Api.getOauth2Applications();
if (!apps) return; if (!apps) return;
if (apps.length === 0) { if (apps.length === 0) {
console.log("No OAuth2 applications found."); console.log("No OAuth2 applications found.");
return; return;
@ -126,32 +126,32 @@ async function main() {
console.error("Credentials not found. Please login first."); console.error("Credentials not found. Please login first.");
return; return;
} }
// Create OAuth2Api with token // Create OAuth2Api with token
const oauth2Api = new OAuth2Api(URL_BASE, credentials.token); const oauth2Api = new OAuth2Api(URL_BASE, credentials.token);
const name = await prompt("Enter the name of the application: "); const name = await prompt("Enter the name of the application: ");
if (!name) { if (!name) {
console.error("Name is required."); console.error("Name is required.");
return; return;
} }
const redirectUris = await prompt("Enter the redirect URIs (comma separated): "); const redirectUris = await prompt("Enter the redirect URIs (comma separated): ");
if (!redirectUris) { if (!redirectUris) {
console.error("Redirect URIs are required."); console.error("Redirect URIs are required.");
return; return;
} }
const app = await oauth2Api.createOauth2Application({ const app = await oauth2Api.createOauth2Application({
name, name,
redirect_uris: redirectUris.split(",").map(uri => uri.trim()), redirect_uris: redirectUris.split(",").map(uri => uri.trim()),
}); });
if (!app) return; if (!app) return;
console.log("OAuth2 application created successfully!"); console.log("OAuth2 application created successfully!");
console.log(prettyOauth2Application(app)); console.log(prettyOauth2Application(app));
// Save secret keys // Save secret keys
const path = await prompt("Enter the path to save the OAuth2 secret keys: "); const path = await prompt("Enter the path to save the OAuth2 secret keys: ");
if (path) { if (path) {
@ -180,50 +180,61 @@ async function main() {
console.error("Credentials not found. Please login first."); console.error("Credentials not found. Please login first.");
return; return;
} }
// Create OAuth2Api with token // Create OAuth2Api with token
const oauth2Api = new OAuth2Api(URL_BASE, credentials.token); const oauth2Api = new OAuth2Api(URL_BASE, credentials.token);
const id = await prompt("Enter the ID of the application to update: "); const id = await prompt("Enter the ID of the application to update: ");
if (!id) { if (!id) {
console.error("ID is required."); console.error("ID is required.");
return; return;
} }
const appId = parseInt(id); const appId = parseInt(id);
if (isNaN(appId)) { if (isNaN(appId)) {
console.error("ID must be a number."); console.error("ID must be a number.");
return; return;
} }
const name = await prompt("Enter the new name of the application: "); const name = await prompt("Enter the new name of the application: ");
if (!name) { if (!name) {
console.error("Name is required."); console.error("Name is required.");
return; return;
} }
const redirectUris = await prompt("Enter the new redirect URIs (comma separated): "); const redirectUris = await prompt("Enter the new redirect URIs (comma separated): ");
if (!redirectUris) { if (!redirectUris) {
console.error("Redirect URIs are required."); console.error("Redirect URIs are required.");
return; return;
} }
const app = await oauth2Api.updateOauth2Application(appId, { const app = await oauth2Api.updateOauth2Application(appId, {
name, name,
redirect_uris: redirectUris.split(",").map(uri => uri.trim()), redirect_uris: redirectUris.split(",").map(uri => uri.trim()),
}); });
if (!app) return; if (!app) return;
console.log("OAuth2 application updated successfully!"); console.log("OAuth2 application updated successfully!");
console.log(prettyOauth2Application(app)); console.log(prettyOauth2Application(app));
// Save secret keys // Save secret keys
const path = await prompt("Enter the path to save the OAuth2 secret keys: "); const path = await prompt("Enter the path to save the OAuth2 secret keys: ");
if (path) { if (path) {
await saveSecretKeys(path, app.client_id, app.client_secret); await saveSecretKeys(path, app.client_id, app.client_secret);
} }
}) })
.command("fetch-config", "Fetch OpenID configuration")
.action(async () => {
const response = await fetch(`${URL_BASE}/.well-known/openid-configuration`);
if (!response.ok) {
console.error("Failed to fetch OpenID configuration:", response.statusText);
return;
}
const config = await response.json();
console.log("OpenID Configuration:", JSON.stringify(config, null, 2));
})
.parse(Deno.args); .parse(Deno.args);
} catch (error) { } catch (error) {
if (error instanceof Error) { if (error instanceof Error) {