Merge branch 'appwrite:main' into fix-replace-all-instances-of-pill-with-badge

This commit is contained in:
Harsh Mahajan
2025-08-05 11:23:01 +05:30
committed by GitHub
24 changed files with 638 additions and 139 deletions
+3
View File
@@ -20,6 +20,9 @@ export async function enterCreditCard(page: Page) {
await stripe.locator('id=Field-cvcInput').fill('123');
await stripe.locator('id=Field-countryInput').selectOption('DE');
await dialog.getByRole('button', { name: 'Add', exact: true }).click();
await page.locator('id=state-picker').click(); // open dropdown
await page.getByRole('option', { name: 'Alabama' }).click();
await dialog.getByRole('button', { name: 'Add', exact: true }).click();
await dialog.waitFor({
state: 'hidden'
});
+5 -5
View File
@@ -5,9 +5,9 @@
<meta
name="description"
content="Appwrite is an open-source platform for building applications at any scale, using your preferred programming languages and tools." />
<link rel="icon" type="image/svg+xml" href="/console/logos/appwrite-icon.svg" />
<link rel="mask-icon" type="image/png" href="/console/logos/appwrite-icon.png" />
<link rel="stylesheet" href="/console/css/loading.css" />
<link rel="icon" type="image/svg+xml" href="%sveltekit.assets%/logos/appwrite-icon.svg" />
<link rel="mask-icon" type="image/png" href="%sveltekit.assets%/logos/appwrite-icon.png" />
<link rel="stylesheet" href="%sveltekit.assets%/css/loading.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
@@ -40,13 +40,13 @@
<div></div>
</div>
<img
src="/console/images/appwrite-logo-light.svg"
src="%sveltekit.assets%/images/appwrite-logo-light.svg"
width="120"
height="22"
class="logo-light"
alt="Appwrite Logo" />
<img
src="/console/images/appwrite-logo-dark.svg"
src="%sveltekit.assets%/images/appwrite-logo-dark.svg"
width="120"
height="22"
class="logo-dark"
+26 -17
View File
@@ -5,6 +5,8 @@
import { initializeStripe, unmountPaymentElement } from '$lib/stores/stripe';
import { Badge, Card, Layout } from '@appwrite.io/pink-svelte';
import type { PaymentMethodData } from '$lib/sdk/billing';
import type { PaymentMethod } from '@stripe/stripe-js';
import StatePicker from './statePicker.svelte';
export let methods: PaymentMethodData[];
export let group: string;
@@ -14,6 +16,9 @@
export let disabledCondition: string = null;
export let setAsDefault = false;
export let showSetAsDefault = false;
export let showState = false;
export let paymentMethod: PaymentMethod | null = null;
export let state: string = '';
let element: HTMLDivElement;
let loader: HTMLDivElement;
@@ -79,25 +84,29 @@
{/each}
<Card.Selector title="Add new payment method" name="$new" bind:group value="$new" />
{#if group === '$new'}
<InputText
id="name"
label="Cardholder name"
placeholder="Cardholder name"
bind:value={name}
required
autofocus={true} />
{#if showState}
<StatePicker card={paymentMethod} bind:state />
{:else}
<InputText
id="name"
label="Cardholder name"
placeholder="Cardholder name"
bind:value={name}
required
autofocus={true} />
<div class="aw-stripe-container" data-private>
<div class="loader-container" bind:this={loader}>
<div class="loader"></div>
<div class="aw-stripe-container" data-private>
<div class="loader-container" bind:this={loader}>
<div class="loader"></div>
</div>
<div bind:this={element}></div>
</div>
<div bind:this={element}></div>
</div>
{#if showSetAsDefault}
<InputChoice
bind:value={setAsDefault}
id="default"
label="Set as default payment method for this organization" />
{#if showSetAsDefault}
<InputChoice
bind:value={setAsDefault}
id="default"
label="Set as default payment method for this organization" />
{/if}
{/if}
{/if}
</Layout.Stack>
+51 -21
View File
@@ -2,12 +2,14 @@
import { FakeModal } from '$lib/components';
import { InputText, Button } from '$lib/elements/forms';
import { createEventDispatcher, onMount } from 'svelte';
import { initializeStripe, submitStripeCard } from '$lib/stores/stripe';
import { initializeStripe, setPaymentMethod, submitStripeCard } from '$lib/stores/stripe';
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { addNotification } from '$lib/stores/notifications';
import { page } from '$app/state';
import { Spinner } from '@appwrite.io/pink-svelte';
import type { PaymentMethod } from '@stripe/stripe-js';
import StatePicker from './statePicker.svelte';
export let show = false;
@@ -16,10 +18,36 @@
let name: string;
let error: string;
let modal: FakeModal;
let showState: boolean = false;
let state: string = '';
let paymentMethod: PaymentMethod | null = null;
async function handleSubmit() {
try {
if (showState && !state) {
throw Error('Please select a state');
}
if (showState) {
const card = await setPaymentMethod(paymentMethod.id, name, state);
modal.closeModal();
await invalidate(Dependencies.PAYMENT_METHODS);
dispatch('submit', card);
addNotification({
type: 'success',
message: 'A new payment method has been added to your account'
});
return;
}
const card = await submitStripeCard(name, page?.params?.organization ?? null);
if (card && Object.hasOwn(card, 'id')) {
if ((card as PaymentMethod).card.country === 'US') {
paymentMethod = card as PaymentMethod;
showState = true;
return;
}
}
modal.closeModal();
await invalidate(Dependencies.PAYMENT_METHODS);
dispatch('submit', card);
@@ -73,28 +101,30 @@
bind:error
onSubmit={handleSubmit}>
<slot />
<InputText
id="name"
required
autofocus={true}
bind:value={name}
label="Cardholder name"
placeholder="Cardholder name" />
<div class="aw-stripe-container" data-private>
{#if isLoading}
<div class="loader-element">
<Spinner />
{#if showState}
<StatePicker card={paymentMethod} bind:state />
{:else}
<InputText
id="name"
required
autofocus={true}
bind:value={name}
label="Cardholder name"
placeholder="Cardholder name" />
<div class="aw-stripe-container" data-private>
{#if isLoading}
<div class="loader-element">
<Spinner />
</div>
{/if}
<div
style:display={isLoading ? 'none' : 'initial'}
class="stripe-element"
bind:this={element}>
<!-- Stripe will create form elements here -->
</div>
{/if}
<div
style:display={isLoading ? 'none' : 'initial'}
class="stripe-element"
bind:this={element}>
<!-- Stripe will create form elements here -->
</div>
</div>
{/if}
<slot name="end"></slot>
<svelte:fragment slot="footer">
<Button secondary on:click={() => (show = false)}>Cancel</Button>
+238
View File
@@ -0,0 +1,238 @@
export const states: Array<{ name: string; abbreviation: string }> = [
{
name: 'Alabama',
abbreviation: 'AL'
},
{
name: 'Alaska',
abbreviation: 'AK'
},
{
name: 'American Samoa',
abbreviation: 'AS'
},
{
name: 'Arizona',
abbreviation: 'AZ'
},
{
name: 'Arkansas',
abbreviation: 'AR'
},
{
name: 'California',
abbreviation: 'CA'
},
{
name: 'Colorado',
abbreviation: 'CO'
},
{
name: 'Connecticut',
abbreviation: 'CT'
},
{
name: 'Delaware',
abbreviation: 'DE'
},
{
name: 'District Of Columbia',
abbreviation: 'DC'
},
{
name: 'Federated States Of Micronesia',
abbreviation: 'FM'
},
{
name: 'Florida',
abbreviation: 'FL'
},
{
name: 'Georgia',
abbreviation: 'GA'
},
{
name: 'Guam',
abbreviation: 'GU'
},
{
name: 'Hawaii',
abbreviation: 'HI'
},
{
name: 'Idaho',
abbreviation: 'ID'
},
{
name: 'Illinois',
abbreviation: 'IL'
},
{
name: 'Indiana',
abbreviation: 'IN'
},
{
name: 'Iowa',
abbreviation: 'IA'
},
{
name: 'Kansas',
abbreviation: 'KS'
},
{
name: 'Kentucky',
abbreviation: 'KY'
},
{
name: 'Louisiana',
abbreviation: 'LA'
},
{
name: 'Maine',
abbreviation: 'ME'
},
{
name: 'Marshall Islands',
abbreviation: 'MH'
},
{
name: 'Maryland',
abbreviation: 'MD'
},
{
name: 'Massachusetts',
abbreviation: 'MA'
},
{
name: 'Michigan',
abbreviation: 'MI'
},
{
name: 'Minnesota',
abbreviation: 'MN'
},
{
name: 'Mississippi',
abbreviation: 'MS'
},
{
name: 'Missouri',
abbreviation: 'MO'
},
{
name: 'Montana',
abbreviation: 'MT'
},
{
name: 'Nebraska',
abbreviation: 'NE'
},
{
name: 'Nevada',
abbreviation: 'NV'
},
{
name: 'New Hampshire',
abbreviation: 'NH'
},
{
name: 'New Jersey',
abbreviation: 'NJ'
},
{
name: 'New Mexico',
abbreviation: 'NM'
},
{
name: 'New York',
abbreviation: 'NY'
},
{
name: 'North Carolina',
abbreviation: 'NC'
},
{
name: 'North Dakota',
abbreviation: 'ND'
},
{
name: 'Northern Mariana Islands',
abbreviation: 'MP'
},
{
name: 'Ohio',
abbreviation: 'OH'
},
{
name: 'Oklahoma',
abbreviation: 'OK'
},
{
name: 'Oregon',
abbreviation: 'OR'
},
{
name: 'Palau',
abbreviation: 'PW'
},
{
name: 'Pennsylvania',
abbreviation: 'PA'
},
{
name: 'Puerto Rico',
abbreviation: 'PR'
},
{
name: 'Rhode Island',
abbreviation: 'RI'
},
{
name: 'South Carolina',
abbreviation: 'SC'
},
{
name: 'South Dakota',
abbreviation: 'SD'
},
{
name: 'Tennessee',
abbreviation: 'TN'
},
{
name: 'Texas',
abbreviation: 'TX'
},
{
name: 'Utah',
abbreviation: 'UT'
},
{
name: 'Vermont',
abbreviation: 'VT'
},
{
name: 'Virgin Islands',
abbreviation: 'VI'
},
{
name: 'Virginia',
abbreviation: 'VA'
},
{
name: 'Washington',
abbreviation: 'WA'
},
{
name: 'West Virginia',
abbreviation: 'WV'
},
{
name: 'Wisconsin',
abbreviation: 'WI'
},
{
name: 'Wyoming',
abbreviation: 'WY'
}
];
@@ -0,0 +1,44 @@
<script lang="ts">
import { states } from './state';
import { InputSelect } from '$lib/elements/forms';
import type { PaymentMethod } from '@stripe/stripe-js';
import { Alert, Card, Layout, Typography } from '@appwrite.io/pink-svelte';
import { CreditCardBrandImage } from '../index.js';
export let state: string = '';
export let card: PaymentMethod | null = null;
</script>
<Layout.Stack direction="column" gap="m">
{#if card}
<Card.Base variant="secondary" padding="s">
<Layout.Stack direction="row" alignItems="center" gap="s">
<CreditCardBrandImage brand={card.card?.brand} />
<span>ending in {card.card?.last4}</span>
</Layout.Stack>
<Typography.Text size="s">
{card.card.country}
{card.billing_details.address.postal_code}
</Typography.Text>
</Card.Base>
{/if}
<Alert.Inline status="info" title="State is required for US payment methods">
<Typography.Text size="s">
To complete the billing information, select your state so we can apply the correct taxes
and meet U.S. legal requirements.
</Typography.Text>
</Alert.Inline>
<InputSelect
bind:value={state}
required
label="State"
placeholder="Select a state"
id="state-picker"
options={states.map((state) => ({
label: state.name,
value: state.abbreviation,
id: state.abbreviation.toLowerCase()
}))} />
</Layout.Stack>
+1 -1
View File
@@ -154,7 +154,7 @@
migrations.migrations.forEach(updateOrAddItem);
});
return sdk.forConsole.client.subscribe('console', (response) => {
return sdk.forConsoleIn(page.params.region).client.subscribe('console', (response) => {
if (!response.channels.includes(`projects.${getProjectId()}`)) return;
if (response.events.includes('migrations.*')) {
updateOrAddItem(response.payload as Payload);
+6 -1
View File
@@ -1111,7 +1111,8 @@ export class Billing {
async setPaymentMethod(
paymentMethodId: string,
providerMethodId: string | PaymentMethod,
name: string
name: string,
state: string | undefined = undefined
): Promise<PaymentMethodData> {
const path = `/account/payment-methods/${paymentMethodId}/provider`;
const params = {
@@ -1119,6 +1120,10 @@ export class Billing {
providerMethodId,
name
};
if (state !== undefined) {
params['state'] = state;
}
const uri = new URL(this.client.config.endpoint + path);
return await this.client.call(
'patch',
+40 -3
View File
@@ -1,4 +1,10 @@
import type { Appearance, Stripe, StripeElement, StripeElements } from '@stripe/stripe-js';
import type {
Appearance,
PaymentMethod,
Stripe,
StripeElement,
StripeElements
} from '@stripe/stripe-js';
import { sdk } from './sdk';
import { app } from './app';
import { get, writable } from 'svelte/store';
@@ -83,7 +89,8 @@ export async function submitStripeCard(name: string, organizationId?: string) {
billing_details: {
name
}
}
},
expand: ['payment_method']
},
redirect: 'if_required'
});
@@ -95,9 +102,13 @@ export async function submitStripeCard(name: string, organizationId?: string) {
}
if (setupIntent && setupIntent.status === 'succeeded') {
if ((setupIntent.payment_method as PaymentMethod).card.country === 'US') {
// need to get state
return setupIntent.payment_method as PaymentMethod;
}
const method = await sdk.forConsole.billing.setPaymentMethod(
paymentMethod.$id,
setupIntent.payment_method,
(setupIntent.payment_method as PaymentMethod).id,
name
);
paymentElement.destroy();
@@ -115,6 +126,32 @@ export async function submitStripeCard(name: string, organizationId?: string) {
}
}
export async function setPaymentMethod(providerMethodId: string, name: string, state: string) {
if (!paymentMethod) {
addNotification({
title: 'Error',
message: 'No payment method found. Please try again.',
type: 'error'
});
return;
}
try {
const method = await sdk.forConsole.billing.setPaymentMethod(
paymentMethod.$id,
providerMethodId,
name,
state
);
paymentElement.destroy();
isStripeInitialized.set(false);
trackEvent(Submit.PaymentMethodCreate);
return method;
} catch (e) {
trackError(e, Submit.PaymentMethodCreate);
throw e;
}
}
export async function confirmPayment(
orgId: string,
clientSecret: string,
@@ -16,12 +16,12 @@
PaginationWithLimit
} from '$lib/components';
import { goto } from '$app/navigation';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { Submit, trackError, trackEvent, Click } from '$lib/actions/analytics';
import { sdk } from '$lib/stores/sdk';
import { loading } from '$routes/store';
import { ID, Region, type Models } from '@appwrite.io/console';
import { openImportWizard } from '../project-[region]-[project]/settings/migrations/(import)';
import { billingProjectsLimitDate, readOnly } from '$lib/stores/billing';
import { billingProjectsLimitDate, readOnly, upgradeURL } from '$lib/stores/billing';
import { onMount, type ComponentType } from 'svelte';
import { canWriteProjects } from '$lib/stores/roles';
import { checkPricingRefAndRedirect } from '$lib/helpers/pricingRedirect';
@@ -184,6 +184,17 @@
<Button secondary size="s" on:click={() => (showSelectProject = true)}>
Manage projects
</Button>
<Button
size="s"
href={$upgradeURL}
on:click={() => {
trackEvent(Click.OrganizationClickUpgrade, {
from: 'button',
source: 'projects_archive_alert'
});
}}>
Upgrade to Pro
</Button>
</svelte:fragment>
</Alert.Inline>
{/if}
@@ -5,12 +5,13 @@
import { sdk } from '$lib/stores/sdk';
import type { Organization } from '$lib/stores/organization';
import { Dependencies } from '$lib/constants';
import { submitStripeCard } from '$lib/stores/stripe';
import { setPaymentMethod, submitStripeCard } from '$lib/stores/stripe';
import { onMount } from 'svelte';
import type { PaymentList } from '$lib/sdk/billing';
import type { PaymentList, PaymentMethodData } from '$lib/sdk/billing';
import { addNotification } from '$lib/stores/notifications';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { PaymentBoxes } from '$lib/components/billing';
import type { PaymentMethod } from '@stripe/stripe-js';
export let organization: Organization;
export let show = false;
@@ -20,6 +21,9 @@
let name: string;
let error: string;
let selectedPaymentMethodId: string;
let showState: boolean = false;
let state: string = '';
let paymentMethod: PaymentMethod | null = null;
onMount(async () => {
if (!organization.paymentMethodId && !organization.backupPaymentMethodId) {
@@ -41,7 +45,24 @@
async function handleSubmit() {
try {
if (selectedPaymentMethodId === '$new') {
const method = await submitStripeCard(name, organization.$id);
if (showState && !state) {
throw Error('Please select a state');
}
let method: PaymentMethodData;
if (showState) {
method = await setPaymentMethod(paymentMethod.id, name, state);
} else {
const card = await submitStripeCard(name, organization.$id);
if (card && Object.hasOwn(card, 'id')) {
if ((card as PaymentMethod).card.country === 'US') {
paymentMethod = card as PaymentMethod;
showState = true;
return;
}
} else if (card && Object.hasOwn(card, '$id')) {
method = card as PaymentMethodData;
}
}
selectedPaymentMethodId = method.$id;
}
isBackup
@@ -97,6 +118,9 @@
<PaymentBoxes
methods={filteredMethods}
bind:name
bind:paymentMethod
bind:showState
bind:state
bind:group={selectedPaymentMethodId}
defaultMethod={organization?.paymentMethodId}
backupMethod={organization?.backupPaymentMethodId}
@@ -3,11 +3,16 @@
import { FakeModal } from '$lib/components';
import { Button } from '$lib/elements/forms';
import { Dependencies } from '$lib/constants';
import type { Invoice } from '$lib/sdk/billing';
import type { Invoice, PaymentMethodData } from '$lib/sdk/billing';
import { addNotification } from '$lib/stores/notifications';
import { Submit, trackError, trackEvent } from '$lib/actions/analytics';
import { page } from '$app/state';
import { confirmPayment, isStripeInitialized, submitStripeCard } from '$lib/stores/stripe';
import {
confirmPayment,
isStripeInitialized,
setPaymentMethod,
submitStripeCard
} from '$lib/stores/stripe';
import { organization } from '$lib/stores/organization';
import { toLocaleDate } from '$lib/helpers/date';
import { PaymentBoxes } from '$lib/components/billing';
@@ -16,6 +21,7 @@
import { getApiEndpoint, sdk } from '$lib/stores/sdk';
import { formatCurrency } from '$lib/helpers/numbers';
import { base } from '$app/paths';
import type { PaymentMethod } from '@stripe/stripe-js';
export let show = false;
export let invoice: Invoice;
@@ -24,6 +30,9 @@
let name: string;
let paymentMethodId: string;
let setAsDefault = false;
let showState: boolean = false;
let state: string = '';
let paymentMethod: PaymentMethod | null = null;
const endpoint = getApiEndpoint();
onMount(async () => {
@@ -48,7 +57,24 @@
try {
if (paymentMethodId === null) {
try {
const method = await submitStripeCard(name, $organization.$id);
if (showState && !state) {
throw Error('Please select a state');
}
let method: PaymentMethodData;
if (showState) {
method = await setPaymentMethod(paymentMethod.id, name, state);
} else {
const card = await submitStripeCard(name, $organization.$id);
if (card && Object.hasOwn(card, 'id')) {
if ((card as PaymentMethod).card.country === 'US') {
paymentMethod = card as PaymentMethod;
showState = true;
return;
}
} else if (card && Object.hasOwn(card, '$id')) {
method = card as PaymentMethodData;
}
}
const card = await sdk.forConsole.billing.getPaymentMethod(method.$id);
if (card?.last4) {
paymentMethodId = card.$id;
@@ -131,6 +157,9 @@
</Button>
<PaymentBoxes
bind:paymentMethod
bind:showState
bind:state
methods={filteredMethods}
defaultMethod={$organization?.paymentMethodId}
backupMethod={$organization?.backupPaymentMethodId}
@@ -1,17 +1,21 @@
<script lang="ts">
import { WizardStep } from '$lib/layout';
import { onMount } from 'svelte';
import type { PaymentList } from '$lib/sdk/billing';
import type { PaymentList, PaymentMethodData } from '$lib/sdk/billing';
import { invalidate } from '$app/navigation';
import { Dependencies } from '$lib/constants';
import { isStripeInitialized, submitStripeCard } from '$lib/stores/stripe';
import { isStripeInitialized, setPaymentMethod, submitStripeCard } from '$lib/stores/stripe';
import { sdk } from '$lib/stores/sdk';
import { PaymentBoxes } from '$lib/components/billing';
import { addCreditWizardStore } from '../store';
import { organization } from '$lib/stores/organization';
import type { PaymentMethod } from '@stripe/stripe-js';
let methods: PaymentList;
let name: string;
let showState: boolean = false;
let state: string = '';
let paymentMethod: PaymentMethod | null = null;
onMount(async () => {
methods = await sdk.forConsole.billing.listPaymentMethods();
@@ -21,7 +25,24 @@
async function handleSubmit() {
try {
const method = await submitStripeCard(name, $organization.$id);
if (showState && !state) {
throw Error('Please select a state');
}
let method: PaymentMethodData;
if (showState) {
method = await setPaymentMethod(paymentMethod.id, name, state);
} else {
const card = await submitStripeCard(name, $organization.$id);
if (card && Object.hasOwn(card, 'id')) {
if ((card as PaymentMethod).card.country === 'US') {
paymentMethod = card as PaymentMethod;
showState = true;
return;
}
} else if (card && Object.hasOwn(card, '$id')) {
method = card as PaymentMethodData;
}
}
$addCreditWizardStore.paymentMethodId = method.$id;
invalidate(Dependencies.PAYMENT_METHODS);
} catch (e) {
@@ -45,6 +66,9 @@
<p class="text"><b>Payment method</b></p>
<PaymentBoxes
bind:paymentMethod
bind:showState
bind:state
methods={filteredMethods}
bind:name
bind:group={$addCreditWizardStore.paymentMethodId} />
@@ -5,12 +5,17 @@
import { Link } from '$lib/elements';
import type { Models } from '@appwrite.io/console';
let { domain, retryVerification }: { domain: Models.Domain; retryVerification: () => void } =
$props();
let {
domain,
retryVerification
}: {
domain: Models.Domain;
retryVerification: () => void;
} = $props();
const isDomainVerified = domain.nameservers.toLowerCase() === 'appwrite';
const isDomainVerified = $derived(domain.nameservers.toLowerCase() === 'appwrite');
const metrics = [
const metrics = $derived([
{
value: isDomainVerified ? 'Verified' : 'Not verified',
description: 'Status'
@@ -40,7 +45,7 @@
value: domain?.renewalPrice || '-',
description: 'Renewal price'
}
];
]);
</script>
<Layout.Grid gap="m" columnsL={6} columns={3} columnsS={2} columnsXXS={1}>
@@ -60,10 +60,11 @@
label="Services ID"
autofocus={true}
placeholder="com.company.appname"
bind:value={appId} />
<InputText id="keyID" label="Key ID" placeholder="SHAB13ROFN" bind:value={keyID} />
<InputText id="teamID" label="Team ID" placeholder="ELA2CD3AED" bind:value={teamID} />
<InputTextarea id="p8" label="P8 File" placeholder="" bind:value={p8} />
bind:value={appId}
required />
<InputText id="keyID" label="Key ID" placeholder="SHAB13ROFN" bind:value={keyID} required />
<InputText id="teamID" label="Team ID" placeholder="ELA2CD3AED" bind:value={teamID} required />
<InputTextarea id="p8" label="P8 File" placeholder="" bind:value={p8} required />
<Alert.Inline status="info">
To complete set up, add this OAuth2 redirect URI to your {provider.name} app configuration.
</Alert.Inline>
@@ -73,10 +74,13 @@
<svelte:fragment slot="footer">
<Button secondary on:click={() => (provider = null)}>Cancel</Button>
<Button
disabled={(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId) ||
!(appId && keyID && teamID && p8)}
disabled={!appId ||
!keyID ||
!teamID ||
!p8 ||
(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId)}
submit>Update</Button>
</svelte:fragment>
</Modal>
@@ -56,18 +56,21 @@
label="Client ID"
autofocus={true}
placeholder="Enter ID"
bind:value={appId} />
bind:value={appId}
required />
<InputPassword
id="secret"
label="Client Secret"
placeholder="Enter Client Secret"
minlength={0}
bind:value={clientSecret} />
bind:value={clientSecret}
required />
<InputText
id="domain"
label="Auth0 Domain"
placeholder="Your Auth0 domain"
bind:value={auth0Domain} />
placeholder="your-tenant.auth0.com"
bind:value={auth0Domain}
required />
<Alert.Inline status="info">
To complete set up, add this OAuth2 redirect URI to your {provider.name} app configuration.
</Alert.Inline>
@@ -77,10 +80,12 @@
<svelte:fragment slot="footer">
<Button secondary on:click={() => (provider = null)}>Cancel</Button>
<Button
disabled={(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId) ||
!(appId && clientSecret && auth0Domain)}
disabled={!appId ||
!clientSecret ||
!auth0Domain ||
(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId)}
submit>Update</Button>
</svelte:fragment>
</Modal>
@@ -60,18 +60,21 @@
label="Client ID"
autofocus={true}
placeholder="Enter ID"
bind:value={appId} />
bind:value={appId}
required />
<InputPassword
id="secret"
label="Client Secret"
placeholder="Enter Client Secret"
minlength={0}
bind:value={clientSecret} />
bind:value={clientSecret}
required />
<InputText
id="domain"
label="Authentik Base-Domain"
placeholder="Your Authentik domain"
bind:value={authentikDomain} />
bind:value={authentikDomain}
required />
<Alert.Inline status="info">
To complete set up, add this OAuth2 redirect URI to your {provider.name} app configuration.
</Alert.Inline>
@@ -81,10 +84,12 @@
<svelte:fragment slot="footer">
<Button secondary on:click={() => (provider = null)}>Cancel</Button>
<Button
disabled={(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId) ||
!(appId && clientSecret && authentikDomain)}
disabled={!appId ||
!clientSecret ||
!authentikDomain ||
(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId)}
submit>Update</Button>
</svelte:fragment>
</Modal>
@@ -55,18 +55,16 @@
label="App ID"
autofocus={true}
placeholder="Enter ID"
bind:value={appId} />
bind:value={appId}
required />
<InputPassword
id="secret"
label="App Secret"
placeholder="Enter App Secret"
minlength={0}
bind:value={clientSecret} />
<InputText
id="endpoint"
label="Endpoint (optional)"
placeholder="Your endpoint"
bind:value={endpoint} />
bind:value={clientSecret}
required />
<InputText id="endpoint" label="Endpoint" placeholder="Your endpoint" bind:value={endpoint} />
<Alert.Inline status="info">
To complete set up, add this OAuth2 redirect URI to your {provider.name} app configuration.
</Alert.Inline>
@@ -76,10 +74,11 @@
<svelte:fragment slot="footer">
<Button secondary on:click={() => (provider = null)}>Cancel</Button>
<Button
disabled={(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId) ||
!(appId && clientSecret)}
disabled={!appId ||
!clientSecret ||
(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId)}
submit>Update</Button>
</svelte:fragment>
</Modal>
@@ -54,13 +54,15 @@
label="App ID"
autofocus={true}
placeholder="Enter ID"
bind:value={appId} />
bind:value={appId}
required />
<InputPassword
id="secret"
label="App Secret"
placeholder="Enter App Secret"
minlength={0}
bind:value={secret} />
bind:value={secret}
required />
<Alert.Inline status="info">
To complete the setup, create an OAuth2 client ID with "Web application" as the application
type, then add this redirect URI to your {provider.name} configuration.
@@ -74,9 +76,9 @@
<Button
disabled={!appId ||
!secret ||
(appId === provider.appId &&
secret === provider.secret &&
enabled === provider.enabled)}
(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId)}
submit>Update</Button>
</svelte:fragment>
</Modal>
@@ -55,13 +55,15 @@
label="App ID"
autofocus={true}
placeholder="Enter ID"
bind:value={appId} />
bind:value={appId}
required />
<InputPassword
id="secret"
label="App Secret"
placeholder="Enter App Secret"
minlength={0}
bind:value={secret} />
bind:value={secret}
required />
<Alert.Inline status="info">
To complete set up, add this OAuth2 redirect URI to your {provider.name} app configuration.
</Alert.Inline>
@@ -73,9 +75,9 @@
<Button
disabled={!appId ||
!secret ||
(appId === provider.appId &&
secret === provider.secret &&
enabled === provider.enabled)}
(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId)}
submit>Update</Button>
</svelte:fragment>
</Modal>
@@ -42,9 +42,8 @@
clientSecret && tenantID ? JSON.stringify({ clientSecret, tenantID }) : provider.secret;
</script>
<Modal {error} onSubmit={update} bind:show on:close>
<svelte:fragment slot="title">{provider.name} OAuth2 settings</svelte:fragment>
<p>
<Modal {error} onSubmit={update} bind:show on:close title={`${provider.name} OAuth2 settings`}>
<p slot="description">
To use {provider.name} authentication in your application, first fill in this form. For more
info you can
<a class="link" href={oAuthProvider?.docs} target="_blank" rel="noopener noreferrer">
@@ -57,13 +56,15 @@
label="Application (client) ID"
autofocus={true}
placeholder="Enter ID"
bind:value={appId} />
bind:value={appId}
required />
<InputPassword
id="secret"
label="Client Secret"
placeholder="Enter Client Secret"
minlength={0}
bind:value={clientSecret} />
bind:value={clientSecret}
required />
<InputText
id="tenant"
label="Target Tenant"
@@ -78,10 +79,11 @@
<svelte:fragment slot="footer">
<Button secondary on:click={() => (provider = null)}>Cancel</Button>
<Button
disabled={(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId) ||
!(appId && clientSecret && tenantID)}
disabled={!appId ||
!clientSecret ||
(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId)}
submit>Update</Button>
</svelte:fragment>
</Modal>
@@ -78,33 +78,39 @@
label="Client ID"
autofocus={true}
placeholder="Enter ID"
bind:value={appId} />
bind:value={appId}
required />
<InputPassword
id="secret"
label="Client Secret"
placeholder="Enter Client Secret"
minlength={0}
bind:value={clientSecret} />
bind:value={clientSecret}
required />
<InputText
id="well-known-endpoint"
label="Well-Known Endpoint"
placeholder="https://example.com/.well-known/openid-configuration"
bind:value={wellKnownEndpoint} />
bind:value={wellKnownEndpoint}
required={!authorizationEndpoint && !tokenEndpoint && !userinfoEndpoint} />
<InputText
id="authorization-endpoint"
label="Authorization Endpoint"
placeholder="https://example.com/authorize"
bind:value={authorizationEndpoint} />
bind:value={authorizationEndpoint}
required={!wellKnownEndpoint} />
<InputText
id="token-endpoint"
label="Token Endpoint"
placeholder="https://example.com/token"
bind:value={tokenEndpoint} />
bind:value={tokenEndpoint}
required={!wellKnownEndpoint} />
<InputText
id="userinfo-endpoint"
label="User Info Endpoint"
placeholder="https://example.com/userinfo"
bind:value={userinfoEndpoint} />
bind:value={userinfoEndpoint}
required={!wellKnownEndpoint} />
<Alert.Inline status="info">
To complete set up, add this OAuth2 redirect URI to your {provider.name} app configuration.
@@ -115,10 +121,13 @@
<svelte:fragment slot="footer">
<Button secondary on:click={() => (provider = null)}>Cancel</Button>
<Button
disabled={(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId) ||
!(appId && isValidSecret)}
disabled={!appId ||
!clientSecret ||
(!wellKnownEndpoint &&
(!authorizationEndpoint || !tokenEndpoint || !userinfoEndpoint)) ||
(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId)}
submit>Update</Button>
</svelte:fragment>
</Modal>
@@ -47,9 +47,14 @@
: provider.secret;
</script>
<Modal {error} onSubmit={update} size="l" bind:show on:close>
<svelte:fragment slot="title">{provider.name} OAuth2 settings</svelte:fragment>
<p>
<Modal
{error}
onSubmit={update}
size="m"
bind:show
on:close
title={`${provider.name} OAuth2 settings`}>
<p slot="description">
To use {provider.name} authentication in your application, first fill in this form. For more
info you can
<a class="link" href={oAuthProvider?.docs} target="_blank" rel="noopener noreferrer"
@@ -61,23 +66,27 @@
label="Client ID"
autofocus={true}
placeholder="Enter ID"
bind:value={appId} />
bind:value={appId}
required />
<InputPassword
id="secret"
label="Client Secret"
placeholder="Enter Client Secret"
minlength={0}
bind:value={clientSecret} />
bind:value={clientSecret}
required />
<InputText
id="domain"
label="Okta Domain"
placeholder="dev-1337.okta.com"
bind:value={oktaDomain} />
bind:value={oktaDomain}
required />
<InputText
id="serverID"
label="Authorization Server ID"
placeholder="default"
bind:value={authorizationServerId} />
bind:value={authorizationServerId}
required />
<Alert.Inline status="info">
To complete set up, add this OAuth2 redirect URI to your {provider.name} app configuration.
@@ -88,10 +97,13 @@
<svelte:fragment slot="footer">
<Button secondary on:click={() => (provider = null)}>Cancel</Button>
<Button
disabled={(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId) ||
!(appId && clientSecret && oktaDomain && authorizationServerId)}
disabled={!appId ||
!clientSecret ||
!oktaDomain ||
!authorizationServerId ||
(secret === provider.secret &&
enabled === provider.enabled &&
appId === provider.appId)}
submit>Update</Button>
</svelte:fragment>
</Modal>
+1 -1
View File
@@ -26,7 +26,7 @@ const config = {
precompress: true
}),
paths: {
base: '/console'
base: process.env.PREVIEW ? '' : '/console'
}
},
vitePlugin: {