Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/renderer/routes/Accounts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { toError } from '../utils/core/logger';
import { saveState } from '../utils/core/storage';
import { getAdapter } from '../utils/forges/registry';
import { openAccountProfile, openAccountSettings, openHost } from '../utils/system/links';
import { getAuthMethodIcon, getPlatformIcon } from '../utils/ui/icons';
import { getPlatformIcon } from '../utils/ui/icons';

export const AccountsRoute: FC = () => {
const navigate = useNavigate();
Expand Down Expand Up @@ -153,7 +153,7 @@ export const AccountsRoute: FC = () => {

<Contents>
{auth.accounts.map((account, i) => {
const AuthMethodIcon = getAuthMethodIcon(account.method);
const AuthMethodIcon = getAdapter(account).getAuthMethodIcon(account.method);
const PlatformIcon = getPlatformIcon(account.platform);
const accountUUID = getAccountUUID(account);
const accountError = getAccountError(account);
Expand Down
8 changes: 8 additions & 0 deletions src/renderer/utils/forges/gitea/adapter.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { KeyIcon } from '@primer/octicons-react';

import { mockGiteaAccount } from '../../../__mocks__/account-mocks';

import type { Hostname, Link, SettingsState, Token } from '../../../types';
Expand Down Expand Up @@ -39,6 +41,12 @@ describe('renderer/utils/forges/gitea/adapter.ts', () => {
'https://gitea.example.com/user/settings/applications',
);
});

it('returns the key icon for every auth method (PAT-only forge today)', () => {
expect(giteaAdapter.getAuthMethodIcon('Personal Access Token')).toBe(KeyIcon);
expect(giteaAdapter.getAuthMethodIcon('GitHub App')).toBe(KeyIcon);
expect(giteaAdapter.getAuthMethodIcon('OAuth App')).toBe(KeyIcon);
});
});

describe('validateToken', () => {
Expand Down
4 changes: 4 additions & 0 deletions src/renderer/utils/forges/gitea/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ export const giteaAdapter: ForgeAdapter = {
getAccountSettingsUrl: (account: Account) =>
`https://${account.hostname}/user/settings/applications` as Link,
documentationUrl: GITEA_DOCS_URL,
// Gitea only supports PAT today, so every method falls through to the key
// icon. Adding device-flow/OAuth support later means returning their icons
// for those branches.
getAuthMethodIcon: () => KeyIcon,

supportsOAuthScopes: false,

Expand Down
8 changes: 8 additions & 0 deletions src/renderer/utils/forges/github/adapter.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AppsIcon, KeyIcon, PersonIcon } from '@primer/octicons-react';

import { mockGitHubCloudAccount } from '../../../__mocks__/account-mocks';

import type { Hostname, Link, SettingsState, Token } from '../../../types';
Expand Down Expand Up @@ -38,6 +40,12 @@ describe('renderer/utils/forges/github/adapter.ts', () => {
);
});

it('maps each auth method to its icon', () => {
expect(githubAdapter.getAuthMethodIcon('GitHub App')).toBe(AppsIcon);
expect(githubAdapter.getAuthMethodIcon('OAuth App')).toBe(PersonIcon);
expect(githubAdapter.getAuthMethodIcon('Personal Access Token')).toBe(KeyIcon);
});

it('wires the device-flow and OAuth-app methods so the context can dispatch via the adapter', () => {
expect(githubAdapter.deviceFlowAuthMethod).toBe('GitHub App');
expect(githubAdapter.startDeviceFlow).toBeDefined();
Expand Down
15 changes: 14 additions & 1 deletion src/renderer/utils/forges/github/adapter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { KeyIcon, MarkGithubIcon, PersonIcon } from '@primer/octicons-react';
import { AppsIcon, KeyIcon, MarkGithubIcon, PersonIcon } from '@primer/octicons-react';

import { Constants } from '../../../constants';

import type { Account, Link, RawGitifyNotification, SettingsState } from '../../../types';
import type { AuthMethod } from '../../auth/types';
import type { ForgeAdapter, NotificationDisplayHelpers, RefreshAccountData } from '../types';

import { extractHostVersion, getDeveloperSettingsURL, getNewTokenURL, isValidToken } from './auth';
Expand Down Expand Up @@ -99,6 +100,7 @@ export const githubAdapter: ForgeAdapter = {
getPersonalAccessTokenSettingsUrl: getNewTokenURL,
getAccountSettingsUrl: getDeveloperSettingsURL,
documentationUrl: Constants.GITHUB_DOCS.PAT_URL as Link,
getAuthMethodIcon: githubAuthMethodIcon,

supportsOAuthScopes: true,

Expand Down Expand Up @@ -143,3 +145,14 @@ function accountHasScopes(
): boolean {
return Constants.OAUTH_SCOPES[group].every(({ name }) => (account.scopes ?? []).includes(name));
}

function githubAuthMethodIcon(method: AuthMethod) {
switch (method) {
case 'GitHub App':
return AppsIcon;
case 'OAuth App':
return PersonIcon;
default:
return KeyIcon;
}
}
6 changes: 6 additions & 0 deletions src/renderer/utils/forges/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,12 @@ export interface ForgeAdapter {
loginMethods: ReadonlyArray<LoginMethodDescriptor>;
/** External documentation link shown in the PAT login route. */
documentationUrl: Link;
/**
* Icon for the given auth method, used in the Accounts list. Adapters that
* only support a subset of `AuthMethod` should return a sensible fallback
* (e.g. KeyIcon) for unknown values rather than throwing.
*/
getAuthMethodIcon(method: AuthMethod): FC<OcticonProps>;

// --- Auth flows ---
// Optional because not every forge supports every flow. Gitea today is
Expand Down
21 changes: 0 additions & 21 deletions src/renderer/utils/ui/__snapshots__/icons.test.ts.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 1 addition & 14 deletions src/renderer/utils/ui/icons.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,7 @@ import {

import { type GitifyPullRequestReview, IconColor } from '../../types';

import {
getAuthMethodIcon,
getDefaultUserIcon,
getPlatformIcon,
getPullRequestReviewIcon,
} from './icons';
import { getDefaultUserIcon, getPlatformIcon, getPullRequestReviewIcon } from './icons';

describe('renderer/utils/icons.ts', () => {
describe('getPullRequestReviewIcon', () => {
Expand Down Expand Up @@ -110,14 +105,6 @@ describe('renderer/utils/icons.ts', () => {
});
});

it('getAuthMethodIcon', () => {
expect(getAuthMethodIcon('GitHub App')).toMatchSnapshot();

expect(getAuthMethodIcon('OAuth App')).toMatchSnapshot();

expect(getAuthMethodIcon('Personal Access Token')).toMatchSnapshot();
});

it('getPlatformIcon', () => {
expect(getPlatformIcon('GitHub Cloud')).toMatchSnapshot();

Expand Down
16 changes: 1 addition & 15 deletions src/renderer/utils/ui/icons.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import type { FC } from 'react';

import {
AppsIcon,
CheckIcon,
CommentIcon,
FeedPersonIcon,
FileDiffIcon,
KeyIcon,
MarkGithubIcon,
type OcticonProps,
OrganizationIcon,
PersonIcon,
ServerIcon,
ShieldCheckIcon,
} from '@primer/octicons-react';
Expand All @@ -21,7 +18,7 @@ import {
type PullRequestApprovalIcon,
type UserType,
} from '../../types';
import type { AuthMethod, PlatformType } from '../auth/types';
import type { PlatformType } from '../auth/types';

export function getPullRequestReviewIcon(
review: GitifyPullRequestReview,
Expand Down Expand Up @@ -60,17 +57,6 @@ export function getPullRequestReviewIcon(
}
}

export function getAuthMethodIcon(method: AuthMethod): FC<OcticonProps> | null {
switch (method) {
case 'GitHub App':
return AppsIcon;
case 'OAuth App':
return PersonIcon;
default:
return KeyIcon;
}
}

export function getPlatformIcon(platform: PlatformType): FC<OcticonProps> | null {
switch (platform) {
case 'Gitea':
Expand Down
Loading