mirror of
https://github.com/iflytek/skillhub.git
synced 2026-11-14 09:01:16 +00:00
fix(auth): bundle OIDC provider login icons
Signed-off-by: Danny5487401 <64348131+Danny5487401@users.noreply.github.com>
This commit is contained in:
parent
3560679793
commit
be5d4516ec
5 changed files with 68 additions and 2 deletions
1
web/public/auth0-logo.svg
Normal file
1
web/public/auth0-logo.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg fill="#EB5424" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Auth0</title><path d="M21.98 7.448L19.62 0H4.347L2.02 7.448c-1.352 4.312.03 9.206 3.815 12.015L12.007 24l6.157-4.552c3.755-2.81 5.182-7.688 3.815-12.015l-6.16 4.58 2.343 7.45-6.157-4.597-6.158 4.58 2.358-7.433-6.188-4.55 7.63-.045L12.008 0l2.356 7.404 7.615.044z"/></svg>
|
||||
|
After Width: | Height: | Size: 365 B |
1
web/public/keycloak-logo.svg
Normal file
1
web/public/keycloak-logo.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="167.117" height="150.658" viewBox="0 0 44.216 39.861"><path d="m88.61 138.456 5.716-9.865 23.018-.004 5.686 9.965.007 19.932-5.691 9.957-23.012.008-5.782-9.965z" style="display:inline;fill:#4d4d4d;fill-opacity:1;stroke-width:.264583" transform="translate(-82.815 -128.588)"/><path d="M88.552 158.481h10.375l-5.699-10.041 4.634-9.982-9.252-.002-5.795 10.065" style="fill:#ededed;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="M102.073 158.481h7.582l6.706-9.773-6.589-10.156h-8.921l-5.373 9.814z" style="fill:#e0e0e0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="m82.815 148.52 5.738 9.964h10.374l-5.636-9.93z" style="fill:#acacac;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="m95.589 148.522 6.484 9.963h7.582l6.601-9.959z" style="fill:#9e9e9e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="m98.157 148.529-1.958.569-1.877-.572 7.667-13.288 1.918 3.316" style="fill:#00b8e3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="m103.9 158.482-1.909 3.332-5.093-5.487-2.58-7.797v-.004h3.838" style="fill:#33c6e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="M94.322 148.526h-.003v.003l-1.918 3.322-1.925-3.307 1.952-3.386 5.728-9.92h3.834" style="fill:#008aaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="M115.42 158.481h11.611l-.007-19.93h-11.605z" style="fill:#d4d4d4;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="M115.42 148.554v9.93h11.59v-9.93z" style="fill:#919191;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="M101.992 161.817h-3.836l-5.755-9.966 1.918-3.321z" style="fill:#00b8e3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="m117.333 148.526-7.669 13.289c-.705-1.036-1.913-3.331-1.913-3.331l5.753-9.959z" style="fill:#008aaa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="m113.495 161.815-3.831-.001 7.67-13.288 1.917-3.317 1.921 3.34m-3.839-.023h-3.828l-5.755-9.973 1.905-3.314 4.658 5.922z" style="fill:#00b8e3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/><path d="M119.25 145.205v.003l-1.917 3.318-7.677-13.286 3.841.002z" style="fill:#33c6e9;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:.330729" transform="translate(-82.815 -128.588)"/></svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
1
web/public/okta-logo.svg
Normal file
1
web/public/okta-logo.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg fill="#007DC1" role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Okta</title><path d="M12 0C5.389 0 0 5.35 0 12s5.35 12 12 12 12-5.35 12-12S18.611 0 12 0zm0 18c-3.325 0-6-2.675-6-6s2.675-6 6-6 6 2.675 6 6-2.675 6-6 6z"/></svg>
|
||||
|
After Width: | Height: | Size: 255 B |
|
|
@ -1,4 +1,6 @@
|
|||
/** @vitest-environment jsdom */
|
||||
import { existsSync } from 'node:fs'
|
||||
import { resolve } from 'node:path'
|
||||
import { cleanup, fireEvent, render, screen } from '@testing-library/react'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import type { AuthMethod } from '@/api/types'
|
||||
|
|
@ -69,6 +71,62 @@ describe('AuthMethodButtonList', () => {
|
|||
expect(screen.queryByText('Login with Password')).toBeNull()
|
||||
})
|
||||
|
||||
it.each([false, true])('uses the Keycloak icon while preserving existing provider icons (compact=%s)', (compact) => {
|
||||
const keycloakMethod: AuthMethod = {
|
||||
id: 'keycloak',
|
||||
methodType: 'OAUTH_REDIRECT',
|
||||
provider: 'Keycloak',
|
||||
displayName: 'Keycloak',
|
||||
actionUrl: '/oauth2/authorization/keycloak',
|
||||
}
|
||||
|
||||
render(<AuthMethodButtonList methods={[keycloakMethod, methods[0]]} compact={compact} />)
|
||||
|
||||
expect(screen.getByRole('img', { name: 'Keycloak' }).getAttribute('src')).toBe('/keycloak-logo.svg')
|
||||
expect(screen.getByRole('img', { name: 'github' }).getAttribute('src')).toBe('/github-logo.svg')
|
||||
})
|
||||
|
||||
it.each([
|
||||
['Auth0', 'auth0'],
|
||||
['OKTA', 'okta'],
|
||||
])('uses the %s provider icon', (provider, icon) => {
|
||||
render(<AuthMethodButtonList methods={[{
|
||||
id: provider,
|
||||
methodType: 'OAUTH_REDIRECT',
|
||||
provider,
|
||||
displayName: provider,
|
||||
actionUrl: `/oauth2/authorization/${provider}`,
|
||||
}]} />)
|
||||
|
||||
expect(screen.getByRole('img', { name: provider }).getAttribute('src')).toBe(`/${icon}-logo.svg`)
|
||||
})
|
||||
|
||||
it.each(['Enterprise SSO', 'constructor', '__proto__'])('uses the packaged OIDC icon for unrecognized provider %s', (provider) => {
|
||||
render(<AuthMethodButtonList methods={[{
|
||||
id: 'enterprise-sso',
|
||||
methodType: 'OAUTH_REDIRECT',
|
||||
provider,
|
||||
displayName: provider,
|
||||
actionUrl: '/oauth2/authorization/enterprise-sso',
|
||||
}]} />)
|
||||
|
||||
expect(screen.getByRole('img', { name: provider }).getAttribute('src')).toBe('/oidc-logo.svg')
|
||||
})
|
||||
|
||||
it.each(['github', 'gitlab', 'feishu', 'dingtalk', 'keycloak', 'auth0', 'okta', 'unknown'])('bundles the icon selected for %s', (provider) => {
|
||||
render(<AuthMethodButtonList methods={[{
|
||||
id: provider,
|
||||
methodType: 'OAUTH_REDIRECT',
|
||||
provider,
|
||||
displayName: provider,
|
||||
actionUrl: `/oauth2/authorization/${provider}`,
|
||||
}]} />)
|
||||
|
||||
const iconPath = screen.getByRole('img', { name: provider }).getAttribute('src') ?? ''
|
||||
expect(iconPath).toMatch(/^\/[a-z0-9-]+-logo\.svg$/)
|
||||
expect(existsSync(resolve(process.cwd(), 'public', iconPath.slice(1)))).toBe(true)
|
||||
})
|
||||
|
||||
it('renders the supplied empty fallback when no OAuth methods are available', () => {
|
||||
render(<AuthMethodButtonList methods={methods.filter((method) => method.methodType !== 'OAUTH_REDIRECT')} emptyFallback={<p>No methods</p>} />)
|
||||
|
||||
|
|
|
|||
|
|
@ -12,14 +12,19 @@ interface LoginButtonProps {
|
|||
emptyFallback?: React.ReactNode
|
||||
}
|
||||
|
||||
const packagedIconProviders = new Set([
|
||||
'github', 'gitlab', 'feishu', 'dingtalk', 'keycloak', 'auth0', 'okta',
|
||||
])
|
||||
|
||||
/**
|
||||
* Returns the appropriate icon for a given OAuth provider.
|
||||
*/
|
||||
function OAuthIcon({ provider, compact = false }: { provider: string, compact?: boolean }) {
|
||||
const normalizedProvider = provider.toLowerCase()
|
||||
const normalizedProvider = provider.trim().toLowerCase()
|
||||
const iconProvider = packagedIconProviders.has(normalizedProvider) ? normalizedProvider : 'oidc'
|
||||
return (
|
||||
<img
|
||||
src={withBasePath(`/${normalizedProvider}-logo.svg`)}
|
||||
src={withBasePath(`/${iconProvider}-logo.svg`)}
|
||||
alt={provider}
|
||||
className={cn(compact ? 'h-4 w-4' : 'h-5 w-5 mr-3')}
|
||||
/>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue