diff --git a/.changeset/flat-colts-enjoy.md b/.changeset/flat-colts-enjoy.md new file mode 100644 index 0000000..f664647 --- /dev/null +++ b/.changeset/flat-colts-enjoy.md @@ -0,0 +1,7 @@ +--- +'gov4git-desktop-app': patch +--- + +Check PAT privileges prior to logging in. + +- Addresses #39, #40, and gov4git/gov4git#133 diff --git a/src/electron/services/ConfigService.ts b/src/electron/services/ConfigService.ts index cf47879..be3f6fb 100644 --- a/src/electron/services/ConfigService.ts +++ b/src/electron/services/ConfigService.ts @@ -333,6 +333,14 @@ export class ConfigService extends AbstractConfigService { const errors: string[] = [] const user = config.user! + const scopes = await this.gitService.getOAuthScopes(user.pat) + if (!scopes.includes('repo')) { + errors.push( + 'Personal Access Token has insufficient privileges. Please ensure PAT has rights to top-level repo scope.', + ) + return errors + } + if (!(await this.gitService.doesUserExist(user as GitUserInfo))) { errors.push(`Invalid user credentials`) } diff --git a/src/electron/services/GitService.ts b/src/electron/services/GitService.ts index bd18f55..eb9e83a 100644 --- a/src/electron/services/GitService.ts +++ b/src/electron/services/GitService.ts @@ -36,6 +36,17 @@ export class GitService { } } + public getOAuthScopes = async (token: string): Promise => { + const response = await fetch(`${this.apiBaseUrl}`, { + method: 'GET', + headers: { + Authorization: `Token ${token}`, + }, + }) + const scopes = (response.headers.get('X-OAuth-Scopes') ?? '').split(', ') + return scopes + } + protected throwIfUserDoesNotExist = async ( user: GitUserInfo, from: string, diff --git a/src/renderer/src/components/SettingsForm.tsx b/src/renderer/src/components/SettingsForm.tsx index f1af7c9..8c4b3ad 100644 --- a/src/renderer/src/components/SettingsForm.tsx +++ b/src/renderer/src/components/SettingsForm.tsx @@ -73,6 +73,7 @@ export const SettingsForm = function SettingsForm() { eventBus.emit('user-logged-in') } } catch (ex) { + setLoading(false) await catchError(`Failed to save config. ${ex}`) } },