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
41 changes: 23 additions & 18 deletions src/frontend/src/lib/components/modals/auth/AuthConfigModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import type { PrincipalText } from '@dfinity/zod-schemas';
import type { Principal } from '@icp-sdk/core/principal';
import AuthConfigFormCore from '$lib/components/satellites/auth/AuthConfigFormCore.svelte';
import AuthConfigFormGoogle from '$lib/components/satellites/auth/AuthConfigFormGoogle.svelte';
import AuthConfigFormII from '$lib/components/satellites/auth/AuthConfigFormII.svelte';
import AuthConfigFormOpenId from '$lib/components/satellites/auth/AuthConfigFormOpenId.svelte';
import Modal from '$lib/components/ui/Modal.svelte';
import SpinnerModal from '$lib/components/ui/SpinnerModal.svelte';
import { authIdentity } from '$lib/derived/auth.derived';
Expand Down Expand Up @@ -34,10 +34,12 @@

let rule = $derived('core' in detail ? detail.core.rule : undefined);

let edit = $derived<'core' | 'internet_identity' | 'google'>(
'core' in detail ? 'core' : 'internet_identity' in detail ? 'internet_identity' : 'google'
let edit = $derived<'core' | 'internet_identity' | 'openid'>(
'core' in detail ? 'core' : 'internet_identity' in detail ? 'internet_identity' : 'openid'
);

let openidProvider = $derived('openid' in detail ? detail.openid.provider : null);

let config = $derived(detail.config);

// Core rules
Expand All @@ -48,10 +50,10 @@
let selectedDerivationOrigin = $state<URL | undefined>(undefined);
let externalAlternativeOrigins = $state('');

// Google
let googleClientId = $state<string | undefined>(undefined);
let googleMaxTimeToLive = $state<bigint | undefined>(undefined);
let googleAllowedTargets = $state<PrincipalText[] | null | undefined>(undefined);
// OpenId (Google and GitHub)
let openidClientId = $state<string | undefined>(undefined);
let openidMaxTimeToLive = $state<bigint | undefined>(undefined);
let openidAllowedTargets = $state<PrincipalText[] | null | undefined>(undefined);

let step: 'init' | 'in_progress' | 'ready' | 'error' = $state('init');

Expand All @@ -76,12 +78,13 @@
});
}

if (edit === 'google') {
if (edit === 'openid') {
return updateAuthConfigGoogle({
...commonPayload,
clientId: googleClientId,
maxTimeToLive: googleMaxTimeToLive,
allowedTargets: $state.snapshot(googleAllowedTargets)
provider: openidProvider,
clientId: openidClientId,
maxTimeToLive: openidMaxTimeToLive,
allowedTargets: $state.snapshot(openidAllowedTargets)
});
}

Expand All @@ -95,9 +98,10 @@

const { success } = await update();

if (isSkylab() && edit === 'google') {
if (isSkylab() && nonNullish(openidProvider)) {
await emulatorToggleOpenIdMonitoring({
enable: nonNullish(googleClientId)
enable: nonNullish(openidClientId),
provider: openidProvider
});
}

Expand All @@ -124,14 +128,15 @@
<SpinnerModal>
<p>{$i18n.core.updating_configuration}</p>
</SpinnerModal>
{:else if edit === 'google'}
<AuthConfigFormGoogle
{:else if edit === 'openid' && nonNullish(openidProvider)}
<AuthConfigFormOpenId
{config}
onsubmit={handleSubmit}
provider={openidProvider}
{satellite}
bind:clientId={googleClientId}
bind:maxTimeToLive={googleMaxTimeToLive}
bind:allowedTargets={googleAllowedTargets}
bind:clientId={openidClientId}
bind:maxTimeToLive={openidMaxTimeToLive}
bind:allowedTargets={openidAllowedTargets}
/>
{:else if edit === 'internet_identity'}
<AuthConfigFormII
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import { onMount } from 'svelte';
import { fade } from 'svelte/transition';
import type { SatelliteDid } from '$declarations';
import AuthConfigFormGoogleOptions from '$lib/components/satellites/auth/AuthConfigFormGoogleOptions.svelte';
import AuthConfigFormOpenIdOptions from '$lib/components/satellites/auth/AuthConfigFormOpenIdOptions.svelte';
import Input from '$lib/components/ui/Input.svelte';
import Value from '$lib/components/ui/Value.svelte';
import Warning from '$lib/components/ui/Warning.svelte';
Expand All @@ -22,8 +22,10 @@
} from '$lib/constants/duration.constants';
import { isBusy } from '$lib/derived/app/busy.derived';
import { i18n } from '$lib/stores/app/i18n.store';
import type { OpenIdAuthProvider } from '$lib/types/auth';
import type { Satellite } from '$lib/types/satellite';
import { i18nFormat } from '$lib/utils/i18n.utils';
import { findProviderGitHub, findProviderGoogle } from '$lib/utils/auth.openid.utils';
import { i18nCapitalize, i18nFormat } from '$lib/utils/i18n.utils';

interface Props {
satellite: Satellite;
Expand All @@ -32,6 +34,7 @@
clientId: string | undefined;
maxTimeToLive: bigint | undefined;
allowedTargets: PrincipalText[] | null | undefined;
provider: OpenIdAuthProvider;
}

let {
Expand All @@ -40,15 +43,19 @@
config,
clientId = $bindable(undefined),
maxTimeToLive = $bindable(),
allowedTargets = $bindable(undefined)
allowedTargets = $bindable(undefined),
provider
}: Props = $props();

// svelte-ignore state_referenced_locally
let findProvider = $state(provider === 'github' ? findProviderGitHub : findProviderGoogle);

// svelte-ignore state_referenced_locally
let openid = $state(fromNullable(config?.openid ?? []));
let google = $state(openid?.providers.find(([key]) => 'Google' in key));
let providerData = $state(google?.[1]);
let openidProvider = $state(findProvider(openid));
let providerData = $state(openidProvider?.[1]);
let delegation = $state(fromNullable(providerData?.delegation ?? []));
let googleEnabled = $state(nonNullish(google));
let openidEnabled = $state(nonNullish(openidProvider));

// Client ID
let currentClientId = $state(providerData?.client_id);
Expand Down Expand Up @@ -89,17 +96,17 @@
let warnClientId = $derived(isEmptyString(clientId) && notEmptyString(currentClientId));
</script>

<h2>Google</h2>
<h2>{provider}</h2>

<p>
{i18nFormat(
googleEnabled
openidEnabled
? $i18n.authentication.edit_provider
: $i18n.authentication.edit_to_enable_provider,
[
{
placeholder: '{0}',
value: 'Google'
value: i18nCapitalize(provider)
}
]
)}
Expand Down Expand Up @@ -153,7 +160,7 @@
</Value>
</div>

<AuthConfigFormGoogleOptions {delegation} {satellite} bind:allowedTargets />
<AuthConfigFormOpenIdOptions {delegation} {satellite} bind:allowedTargets />

{#if warnClientId}
<div class="warn" in:fade>
Expand All @@ -166,3 +173,9 @@
{$i18n.core.submit}
</button>
</form>

<style lang="scss">
h2 {
text-transform: capitalize;
}
</style>
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,31 @@
TWO_WEEKS_NS
} from '$lib/constants/duration.constants';
import { i18n } from '$lib/stores/app/i18n.store';
import type { OpenIdAuthProvider } from '$lib/types/auth';
import { AUTH_CONFIG_CONTEXT_KEY, type AuthConfigContext } from '$lib/types/auth.context';
import type { JunoModalEditAuthConfigDetailType } from '$lib/types/modal';
import type { Satellite } from '$lib/types/satellite';
import { findProviderGitHub, findProviderGoogle } from '$lib/utils/auth.openid.utils';
import { secondsToDuration } from '$lib/utils/date.utils';
import { i18nFormat } from '$lib/utils/i18n.utils';
import { satelliteName } from '$lib/utils/satellite.utils';

interface Props {
satellite: Satellite;
provider: OpenIdAuthProvider;
openModal: (params: JunoModalEditAuthConfigDetailType) => Promise<void>;
}

let { satellite, openModal }: Props = $props();
let { provider, satellite, openModal }: Props = $props();

const { config, supportConfig } = getContext<AuthConfigContext>(AUTH_CONFIG_CONTEXT_KEY);

let findProvider = $derived(provider === 'github' ? findProviderGitHub : findProviderGoogle);

let openid = $derived(fromNullable($config?.openid ?? []));
let google = $derived(openid?.providers.find(([key]) => 'Google' in key));
let openidProvider = $derived(findProvider(openid));

let providerData = $derived(google?.[1]);
let providerData = $derived(openidProvider?.[1]);

let clientId = $derived(providerData?.client_id);

Expand All @@ -55,12 +60,12 @@

const openEditModal = async () =>
await openModal({
google: null
openid: { provider }
});
</script>

<div class="card-container with-title">
<span class="title">Google</span>
<span class="title">{provider}</span>

<div class="columns-3 fit-column-1">
<div>
Expand Down Expand Up @@ -148,6 +153,10 @@
@use '../../../styles/mixins/text';
@use '../../../styles/mixins/media';

.title {
text-transform: capitalize;
}

p {
&:not(.client-id) {
@include text.truncate;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script lang="ts">
import { setContext } from 'svelte';
import AuthConfigCore from '$lib/components/satellites/auth/AuthConfigCore.svelte';
import AuthConfigGoogle from '$lib/components/satellites/auth/AuthConfigGoogle.svelte';
import AuthConfigII from '$lib/components/satellites/auth/AuthConfigII.svelte';
import AuthConfigOpenId from '$lib/components/satellites/auth/AuthConfigOpenId.svelte';
import AuthProviders from '$lib/components/satellites/auth/AuthProviders.svelte';
import AuthSettingsLoader from '$lib/components/satellites/auth/AuthSettingsLoader.svelte';
import { listCustomDomains } from '$lib/services/satellite/hosting/custom-domain.services';
Expand Down Expand Up @@ -53,7 +53,9 @@
<AuthSettingsLoader {satellite}>
<AuthProviders />

<AuthConfigGoogle {openModal} {satellite} />
<AuthConfigOpenId {openModal} provider="google" {satellite} />

<AuthConfigOpenId {openModal} provider="github" {satellite} />

<AuthConfigII {openModal} />

Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/lib/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@
"auth_domain_config": "Unexpected error(s) while trying to update your authentication configuration.",
"auth_external_alternative_origins": "External alternative origins are malformed. Please provide a valid domain without a protocol.",
"auth_invalid_google_client_id": "Invalid Google client ID pattern detected.",
"auth_undefined_provider": "The provider to configure the OpenId authentication is undefined, which is unexpected.",
"mission_control_not_loaded": "Your Mission Control is not yet loaded.",
"mission_control_not_found": "You don't have a Mission Control.",
"mission_control_settings_not_loaded": "The settings for the Mission Control are not yet loaded.",
Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/lib/i18n/zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@
"auth_domain_config": "更新身份认证配置时发生意外错误。",
"auth_external_alternative_origins": "外部备用源格式错误,请提供不含协议的合法域名。",
"auth_invalid_google_client_id": "检测到无效的 Google 客户端 ID 格式。",
"auth_undefined_provider": "配置 OpenID 身份验证的提供商未定义,这是意外情况。",
"mission_control_not_loaded": "任务控制中心未加载。",
"mission_control_not_found": "您没有任务控制中心。",
"mission_control_settings_not_loaded": "任务控制中心设置未加载。",
Expand Down
7 changes: 5 additions & 2 deletions src/frontend/src/lib/rest/emulator.rest.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { LedgerIdText, WalletId } from '$lib/schemas/wallet.schema';
import { i18n } from '$lib/stores/app/i18n.store';
import type { OpenIdAuthProvider } from '$lib/types/auth';
import { assertNonNullish, isNullish } from '@dfinity/utils';
import { type PrincipalText, PrincipalTextSchema } from '@dfinity/zod-schemas';
import { encodeIcrcAccount } from '@icp-sdk/canisters/ledger/icrc';
Expand Down Expand Up @@ -55,16 +56,18 @@ export const emulatorLedgerTransfer = async ({
};

export const emulatorObservatoryMonitoringOpenId = async ({
action
action,
provider
}: {
action: 'start' | 'stop';
provider: OpenIdAuthProvider;
}) => {
const { VITE_EMULATOR_ADMIN_URL } = import.meta.env;

assertNonNullish(VITE_EMULATOR_ADMIN_URL);

const response = await fetch(
`${VITE_EMULATOR_ADMIN_URL}/observatory/monitoring/openid/?action=${action}`
`${VITE_EMULATOR_ADMIN_URL}/observatory/monitoring/openid/?action=${action}&provider=${provider}`
);

if (!response.ok) {
Expand Down
12 changes: 10 additions & 2 deletions src/frontend/src/lib/services/emulator.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { addSatellitesAdminAccessKey } from '$lib/services/access-keys/satellite
import { i18n } from '$lib/stores/app/i18n.store';
import { toasts } from '$lib/stores/app/toasts.store';
import type { AddAdminAccessKeyParams } from '$lib/types/access-keys';
import type { OpenIdAuthProvider } from '$lib/types/auth';
import type { Identity } from '@icp-sdk/core/agent';
import type { Principal } from '@icp-sdk/core/principal';
import { get } from 'svelte/store';
Expand Down Expand Up @@ -56,14 +57,21 @@ const unsafeSetEmulatorController = async ({
});
};

export const emulatorToggleOpenIdMonitoring = async ({ enable }: { enable: boolean }) => {
export const emulatorToggleOpenIdMonitoring = async ({
enable,
provider
}: {
enable: boolean;
provider: OpenIdAuthProvider;
}) => {
if (isNotSkylab()) {
throw new Error(get(i18n).emulator.error_never_execute_openid_monitoring);
}

try {
await emulatorObservatoryMonitoringOpenId({
action: enable ? 'start' : 'stop'
action: enable ? 'start' : 'stop',
provider
});
} catch (err: unknown) {
toasts.error({
Expand Down
Loading
Loading