feat(extension): update devices.ts for revoked.json + deploy keys

- Add createDeployKey/deleteDeployKey to GiteaHost
- Add RevokedEntry interface and readRevoked() to devices.ts
- Update revokeDevice() to write revoked.json alongside devices.json
- Update router to use new register_device WASM API (private keys internal)
- Pass revokedBy device name when revoking

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
adlee-was-taken
2026-05-02 12:27:14 -04:00
parent 9845febb74
commit 520f6ec72c
3 changed files with 82 additions and 12 deletions

View File

@@ -17,6 +17,7 @@ export class GiteaHost implements GitHost {
private baseUrl: string;
private gitApiBase: string;
private commitsUrl: string;
private keysUrl: string;
private branch: string = 'main';
private headers: Record<string, string>;
@@ -27,6 +28,7 @@ export class GiteaHost implements GitHost {
this.baseUrl = `${apiUrl}/repos/${repoPath}/contents`;
this.gitApiBase = `${apiUrl}/repos/${repoPath}/git`;
this.commitsUrl = `${apiUrl}/repos/${repoPath}/commits`;
this.keysUrl = `${apiUrl}/repos/${repoPath}/keys`;
this.headers = {
'Authorization': `token ${apiToken}`,
'Content-Type': 'application/json',
@@ -244,4 +246,31 @@ export class GiteaHost implements GitHost {
async deleteBlob(path: string, message: string): Promise<void> {
return this.deleteFile(path, message);
}
/// Create a deploy key for this repo, returning its numeric ID.
async createDeployKey(title: string, publicKey: string): Promise<number> {
const resp = await fetch(this.keysUrl, {
method: 'POST',
headers: this.headers,
body: JSON.stringify({ title, key: publicKey, read_only: false }),
});
if (!resp.ok) {
const text = await resp.text();
throw new Error(`createDeployKey: ${resp.status} ${text}`);
}
const json = await resp.json() as { id: number };
return json.id;
}
/// Delete a deploy key by numeric ID. Ignores 404 (already gone).
async deleteDeployKey(keyId: number): Promise<void> {
const resp = await fetch(`${this.keysUrl}/${keyId}`, {
method: 'DELETE',
headers: this.headers,
});
if (!resp.ok && resp.status !== 404) {
const text = await resp.text();
throw new Error(`deleteDeployKey: ${resp.status} ${text}`);
}
}
}