diff --git a/packages/console/src/pages/ConnectorDetails/index.tsx b/packages/console/src/pages/ConnectorDetails/index.tsx
index 760df8381..29ac6cdc0 100644
--- a/packages/console/src/pages/ConnectorDetails/index.tsx
+++ b/packages/console/src/pages/ConnectorDetails/index.tsx
@@ -3,7 +3,7 @@ import { AppearanceMode, ConnectorType } from '@logto/schemas';
import classNames from 'classnames';
import { useState } from 'react';
import { toast } from 'react-hot-toast';
-import { useTranslation } from 'react-i18next';
+import { Trans, useTranslation } from 'react-i18next';
import { useNavigate, useParams } from 'react-router-dom';
import useSWR, { useSWRConfig } from 'swr';
@@ -14,6 +14,7 @@ import Reset from '@/assets/images/reset.svg';
import ActionMenu, { ActionMenuItem } from '@/components/ActionMenu';
import Button from '@/components/Button';
import Card from '@/components/Card';
+import ConfirmModal from '@/components/ConfirmModal';
import CopyToClipboard from '@/components/CopyToClipboard';
import DetailsSkeleton from '@/components/DetailsSkeleton';
import Drawer from '@/components/Drawer';
@@ -49,6 +50,18 @@ const ConnectorDetails = () => {
const api = useApi();
const navigate = useNavigate();
const theme = useTheme();
+ const isSocial = data?.type === ConnectorType.Social;
+ const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState(false);
+
+ const onDeleteClick = async () => {
+ if (!isSocial || !inUse) {
+ await handleDelete();
+
+ return;
+ }
+
+ setIsDeleteAlertOpen(true);
+ };
const handleDelete = async () => {
if (!connectorId) {
@@ -65,7 +78,7 @@ const ConnectorDetails = () => {
await mutateGlobal('/api/connectors');
setIsDeleted(true);
- if (data?.type === ConnectorType.Social) {
+ if (isSocial) {
navigate(`/connectors/social`, { replace: true });
} else {
navigate(`/connectors`, { replace: true });
@@ -75,16 +88,14 @@ const ConnectorDetails = () => {
return (
}
title="connector_details.back_to_connectors"
className={styles.backLink}
/>
{isLoading &&
}
{!data && error &&
{`error occurred: ${error.body?.message ?? error.message}`}
}
- {data?.type === ConnectorType.Social && (
-
- )}
+ {isSocial &&
}
{data && (
@@ -137,7 +148,7 @@ const ConnectorDetails = () => {
buttonProps={{ icon:
, size: 'large' }}
title={t('general.more_options')}
>
- {data.type !== ConnectorType.Social && (
+ {!isSocial && (
}
iconClassName={styles.resetIcon}
@@ -152,7 +163,7 @@ const ConnectorDetails = () => {
)}
)}
-
} type="danger" onClick={handleDelete}>
+
} type="danger" onClick={onDeleteClick}>
{t('general.delete')}
@@ -183,6 +194,22 @@ const ConnectorDetails = () => {
/>
)}
+ {data && (
+
{
+ setIsDeleteAlertOpen(false);
+ }}
+ onConfirm={handleDelete}
+ >
+ }}
+ />
+
+ )}
);
};
diff --git a/packages/core/src/__mocks__/connector-base-data.ts b/packages/core/src/__mocks__/connector-base-data.ts
new file mode 100644
index 000000000..71e294abd
--- /dev/null
+++ b/packages/core/src/__mocks__/connector-base-data.ts
@@ -0,0 +1,125 @@
+import type { ConnectorMetadata } from '@logto/connector-kit';
+import { ConnectorPlatform } from '@logto/connector-kit';
+import type { Connector } from '@logto/schemas';
+
+export const mockMetadata: ConnectorMetadata = {
+ id: 'id',
+ target: 'connector',
+ platform: null,
+ name: {
+ en: 'Connector',
+ 'pt-PT': 'Conector',
+ 'zh-CN': '连接器',
+ 'tr-TR': 'Connector',
+ ko: 'Connector',
+ },
+ logo: './logo.png',
+ logoDark: './logo-dark.png',
+ description: {
+ en: 'Connector',
+ 'pt-PT': 'Conector',
+ 'zh-CN': '连接器',
+ 'tr-TR': 'Connector',
+ ko: 'Connector',
+ },
+ readme: 'README.md',
+ configTemplate: 'config-template.json',
+};
+
+export const mockMetadata0: ConnectorMetadata = {
+ ...mockMetadata,
+ id: 'id0',
+ target: 'connector_0',
+ platform: ConnectorPlatform.Universal,
+};
+
+export const mockMetadata1: ConnectorMetadata = {
+ ...mockMetadata,
+ id: 'id1',
+ target: 'connector_1',
+ platform: ConnectorPlatform.Universal,
+};
+
+export const mockMetadata2: ConnectorMetadata = {
+ ...mockMetadata,
+ id: 'id2',
+ target: 'connector_2',
+ platform: ConnectorPlatform.Universal,
+};
+
+export const mockMetadata3: ConnectorMetadata = {
+ ...mockMetadata,
+ id: 'id3',
+ target: 'connector_3',
+ platform: ConnectorPlatform.Universal,
+};
+
+export const mockMetadata4: ConnectorMetadata = {
+ ...mockMetadata,
+ id: 'id4',
+ target: 'connector_4',
+ platform: ConnectorPlatform.Universal,
+};
+
+export const mockMetadata5: ConnectorMetadata = {
+ ...mockMetadata,
+ id: 'id5',
+ target: 'connector_5',
+ platform: ConnectorPlatform.Universal,
+};
+
+export const mockMetadata6: ConnectorMetadata = {
+ ...mockMetadata,
+ id: 'id6',
+ target: 'connector_6',
+ platform: ConnectorPlatform.Universal,
+};
+
+export const mockConnector0: Connector = {
+ id: 'id0',
+ enabled: true,
+ config: {},
+ createdAt: 1_234_567_890_123,
+};
+
+export const mockConnector1: Connector = {
+ id: 'id1',
+ enabled: true,
+ config: {},
+ createdAt: 1_234_567_890_234,
+};
+
+export const mockConnector2: Connector = {
+ id: 'id2',
+ enabled: true,
+ config: {},
+ createdAt: 1_234_567_890_345,
+};
+
+export const mockConnector3: Connector = {
+ id: 'id3',
+ enabled: true,
+ config: {},
+ createdAt: 1_234_567_890_456,
+};
+
+export const mockConnector4: Connector = {
+ id: 'id4',
+ enabled: true,
+ config: {},
+ createdAt: 1_234_567_890_567,
+};
+
+export const mockConnector5: Connector = {
+ id: 'id5',
+ enabled: true,
+ config: {},
+ createdAt: 1_234_567_890_567,
+};
+
+export const mockConnector6: Connector = {
+ id: 'id6',
+ enabled: true,
+ config: {},
+ createdAt: 1_234_567_890_567,
+};
diff --git a/packages/core/src/__mocks__/connector.ts b/packages/core/src/__mocks__/connector.ts
index 69e6c99c2..84181b3f9 100644
--- a/packages/core/src/__mocks__/connector.ts
+++ b/packages/core/src/__mocks__/connector.ts
@@ -1,33 +1,29 @@
import { ConnectorPlatform } from '@logto/connector-kit';
-import type { Connector, ConnectorMetadata } from '@logto/schemas';
+import type { Connector } from '@logto/schemas';
import { ConnectorType } from '@logto/schemas';
import { any } from 'zod';
import type { LogtoConnector } from '@/connectors/types';
-export const mockMetadata: ConnectorMetadata = {
- id: 'id',
- target: 'connector',
- platform: null,
- name: {
- en: 'Connector',
- 'pt-PT': 'Conector',
- 'zh-CN': '连接器',
- 'tr-TR': 'Connector',
- ko: 'Connector',
- },
- logo: './logo.png',
- logoDark: './logo-dark.png',
- description: {
- en: 'Connector',
- 'pt-PT': 'Conector',
- 'zh-CN': '连接器',
- 'tr-TR': 'Connector',
- ko: 'Connector',
- },
- readme: 'README.md',
- configTemplate: 'config-template.json',
-};
+import {
+ mockConnector0,
+ mockConnector1,
+ mockConnector2,
+ mockConnector3,
+ mockConnector4,
+ mockConnector5,
+ mockConnector6,
+ mockMetadata,
+ mockMetadata0,
+ mockMetadata1,
+ mockMetadata2,
+ mockMetadata3,
+ mockMetadata4,
+ mockMetadata5,
+ mockMetadata6,
+} from './connector-base-data';
+
+export { mockMetadata } from './connector-base-data';
export const mockConnector: Connector = {
id: 'id',
@@ -44,104 +40,6 @@ export const mockLogtoConnector = {
configGuard: any(),
};
-const mockMetadata0: ConnectorMetadata = {
- ...mockMetadata,
- id: 'id0',
- target: 'connector_0',
- platform: ConnectorPlatform.Universal,
-};
-
-const mockMetadata1: ConnectorMetadata = {
- ...mockMetadata,
- id: 'id1',
- target: 'connector_1',
- platform: ConnectorPlatform.Universal,
-};
-
-const mockMetadata2: ConnectorMetadata = {
- ...mockMetadata,
- id: 'id2',
- target: 'connector_2',
- platform: ConnectorPlatform.Universal,
-};
-
-const mockMetadata3: ConnectorMetadata = {
- ...mockMetadata,
- id: 'id3',
- target: 'connector_3',
- platform: ConnectorPlatform.Universal,
-};
-
-const mockMetadata4: ConnectorMetadata = {
- ...mockMetadata,
- id: 'id4',
- target: 'connector_4',
- platform: ConnectorPlatform.Universal,
-};
-
-const mockMetadata5: ConnectorMetadata = {
- ...mockMetadata,
- id: 'id5',
- target: 'connector_5',
- platform: ConnectorPlatform.Universal,
-};
-
-const mockMetadata6: ConnectorMetadata = {
- ...mockMetadata,
- id: 'id6',
- target: 'connector_6',
- platform: ConnectorPlatform.Universal,
-};
-
-const mockConnector0: Connector = {
- id: 'id0',
- enabled: true,
- config: {},
- createdAt: 1_234_567_890_123,
-};
-
-const mockConnector1: Connector = {
- id: 'id1',
- enabled: true,
- config: {},
- createdAt: 1_234_567_890_234,
-};
-
-const mockConnector2: Connector = {
- id: 'id2',
- enabled: true,
- config: {},
- createdAt: 1_234_567_890_345,
-};
-
-const mockConnector3: Connector = {
- id: 'id3',
- enabled: true,
- config: {},
- createdAt: 1_234_567_890_456,
-};
-
-const mockConnector4: Connector = {
- id: 'id4',
- enabled: true,
- config: {},
- createdAt: 1_234_567_890_567,
-};
-
-const mockConnector5: Connector = {
- id: 'id5',
- enabled: true,
- config: {},
- createdAt: 1_234_567_890_567,
-};
-
-const mockConnector6: Connector = {
- id: 'id6',
- enabled: true,
- config: {},
- createdAt: 1_234_567_890_567,
-};
-
export const mockConnectorList: Connector[] = [
mockConnector0,
mockConnector1,
@@ -312,3 +210,52 @@ export const mockLogtoConnectors = [
mockWechatConnector,
mockWechatNativeConnector,
];
+
+export const disabledSocialTarget01 = 'disableSocialTarget-id01';
+export const disabledSocialTarget02 = 'disableSocialTarget-id02';
+export const enabledSocialTarget01 = 'enabledSocialTarget-id01';
+
+export const mockSocialConnectors: LogtoConnector[] = [
+ {
+ dbEntry: {
+ id: 'id0',
+ enabled: false,
+ config: {},
+ createdAt: 1_234_567_890_123,
+ },
+ metadata: {
+ ...mockMetadata,
+ target: disabledSocialTarget01,
+ },
+ type: ConnectorType.Social,
+ ...mockLogtoConnector,
+ },
+ {
+ dbEntry: {
+ id: 'id1',
+ enabled: true,
+ config: {},
+ createdAt: 1_234_567_890_123,
+ },
+ metadata: {
+ ...mockMetadata,
+ target: enabledSocialTarget01,
+ },
+ type: ConnectorType.Social,
+ ...mockLogtoConnector,
+ },
+ {
+ dbEntry: {
+ id: 'id2',
+ enabled: false,
+ config: {},
+ createdAt: 1_234_567_890_123,
+ },
+ metadata: {
+ ...mockMetadata,
+ target: disabledSocialTarget02,
+ },
+ type: ConnectorType.Social,
+ ...mockLogtoConnector,
+ },
+];
diff --git a/packages/core/src/lib/sign-in-experience/index.test.ts b/packages/core/src/lib/sign-in-experience/index.test.ts
index 068ebd525..b871a0469 100644
--- a/packages/core/src/lib/sign-in-experience/index.test.ts
+++ b/packages/core/src/lib/sign-in-experience/index.test.ts
@@ -1,22 +1,53 @@
import type { LanguageTag } from '@logto/language-kit';
import { builtInLanguages } from '@logto/phrases-ui';
+import type { CreateSignInExperience, SignInExperience } from '@logto/schemas';
import { BrandingStyle } from '@logto/schemas';
-import { mockBranding } from '@/__mocks__';
+import {
+ disabledSocialTarget01,
+ disabledSocialTarget02,
+ enabledSocialTarget01,
+ mockBranding,
+ mockSignInExperience,
+ mockSocialConnectors,
+} from '@/__mocks__';
+import type { LogtoConnector } from '@/connectors/types';
import RequestError from '@/errors/RequestError';
import {
validateBranding,
validateTermsOfUse,
validateLanguageInfo,
+ removeUnavailableSocialConnectorTargets,
} from '@/lib/sign-in-experience';
+import { updateDefaultSignInExperience } from '@/queries/sign-in-experience';
const allCustomLanguageTags: LanguageTag[] = [];
const findAllCustomLanguageTags = jest.fn(async () => allCustomLanguageTags);
+const getLogtoConnectorsPlaceHolder = jest.fn() as jest.MockedFunction<
+ () => Promise
+>;
+const findDefaultSignInExperience = jest.fn() as jest.MockedFunction<
+ () => Promise
+>;
jest.mock('@/queries/custom-phrase', () => ({
findAllCustomLanguageTags: async () => findAllCustomLanguageTags(),
}));
+jest.mock('@/connectors', () => ({
+ getLogtoConnectors: async () => getLogtoConnectorsPlaceHolder(),
+}));
+
+jest.mock('@/queries/sign-in-experience', () => ({
+ findDefaultSignInExperience: async () => findDefaultSignInExperience(),
+ updateDefaultSignInExperience: jest.fn(
+ async (data: Partial): Promise => ({
+ ...mockSignInExperience,
+ ...data,
+ })
+ ),
+}));
+
beforeEach(() => {
jest.clearAllMocks();
});
@@ -123,3 +154,25 @@ describe('validate terms of use', () => {
}).toMatchError(new RequestError('sign_in_experiences.empty_content_url_of_terms_of_use'));
});
});
+
+describe('remove unavailable social connector targets', () => {
+ test('should remove unavailable social connector targets in sign-in experience', async () => {
+ const mockSocialConnectorTargets = mockSocialConnectors.map(
+ ({ metadata: { target } }) => target
+ );
+ findDefaultSignInExperience.mockResolvedValueOnce({
+ ...mockSignInExperience,
+ socialSignInConnectorTargets: mockSocialConnectorTargets,
+ });
+ getLogtoConnectorsPlaceHolder.mockResolvedValueOnce(mockSocialConnectors);
+ expect(mockSocialConnectorTargets).toEqual([
+ disabledSocialTarget01,
+ enabledSocialTarget01,
+ disabledSocialTarget02,
+ ]);
+ await removeUnavailableSocialConnectorTargets();
+ expect(updateDefaultSignInExperience).toBeCalledWith({
+ socialSignInConnectorTargets: [enabledSocialTarget01],
+ });
+ });
+});
diff --git a/packages/core/src/lib/sign-in-experience/index.ts b/packages/core/src/lib/sign-in-experience/index.ts
index 81d522bde..304544434 100644
--- a/packages/core/src/lib/sign-in-experience/index.ts
+++ b/packages/core/src/lib/sign-in-experience/index.ts
@@ -1,9 +1,14 @@
import { builtInLanguages } from '@logto/phrases-ui';
import type { Branding, LanguageInfo, TermsOfUse } from '@logto/schemas';
-import { BrandingStyle } from '@logto/schemas';
+import { ConnectorType, BrandingStyle } from '@logto/schemas';
+import { getLogtoConnectors } from '@/connectors';
import RequestError from '@/errors/RequestError';
import { findAllCustomLanguageTags } from '@/queries/custom-phrase';
+import {
+ findDefaultSignInExperience,
+ updateDefaultSignInExperience,
+} from '@/queries/sign-in-experience';
import assertThat from '@/utils/assert-that';
export * from './sign-up';
@@ -35,3 +40,19 @@ export const validateTermsOfUse = (termsOfUse: TermsOfUse) => {
'sign_in_experiences.empty_content_url_of_terms_of_use'
);
};
+
+export const removeUnavailableSocialConnectorTargets = async () => {
+ const connectors = await getLogtoConnectors();
+ const availableSocialConnectorTargets = new Set(
+ connectors
+ .filter(({ type, dbEntry: { enabled } }) => enabled && type === ConnectorType.Social)
+ .map(({ metadata: { target } }) => target)
+ );
+
+ const { socialSignInConnectorTargets } = await findDefaultSignInExperience();
+ await updateDefaultSignInExperience({
+ socialSignInConnectorTargets: socialSignInConnectorTargets.filter((target) =>
+ availableSocialConnectorTargets.has(target)
+ ),
+ });
+};
diff --git a/packages/core/src/routes/connector.ts b/packages/core/src/routes/connector.ts
index 0663ed4f6..c03e25fbb 100644
--- a/packages/core/src/routes/connector.ts
+++ b/packages/core/src/routes/connector.ts
@@ -7,6 +7,7 @@ import { object, string } from 'zod';
import { getLogtoConnectorById, getLogtoConnectors } from '@/connectors';
import type { LogtoConnector } from '@/connectors/types';
import RequestError from '@/errors/RequestError';
+import { removeUnavailableSocialConnectorTargets } from '@/lib/sign-in-experience';
import koaGuard from '@/middleware/koa-guard';
import { updateConnector } from '@/queries/connector';
import assertThat from '@/utils/assert-that';
@@ -115,6 +116,12 @@ export default function connectorRoutes(router: T) {
where: { id },
jsonbMode: 'merge',
});
+
+ // Delete the social connector in the sign-in experience if it is disabled.
+ if (!enabled && type === ConnectorType.Social) {
+ await removeUnavailableSocialConnectorTargets();
+ }
+
ctx.body = { ...connector, metadata, type };
return next();
diff --git a/packages/core/src/routes/connector.update.test.ts b/packages/core/src/routes/connector.update.test.ts
index 2bd028b16..3e9eb3094 100644
--- a/packages/core/src/routes/connector.update.test.ts
+++ b/packages/core/src/routes/connector.update.test.ts
@@ -46,6 +46,10 @@ jest.mock('@/connectors', () => ({
getLogtoConnectorById: async (connectorId: string) =>
getLogtoConnectorByIdPlaceholder(connectorId),
}));
+jest.mock('@/lib/sign-in-experience', () => ({
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ removeUnavailableSocialConnectorTargets: async () => {},
+}));
describe('connector PATCH routes', () => {
const connectorRequest = createRequester({ authedRoutes: connectorRoutes });
diff --git a/packages/core/src/routes/session/continue.test.ts b/packages/core/src/routes/session/continue.test.ts
index 3d2af5dea..76d4456fe 100644
--- a/packages/core/src/routes/session/continue.test.ts
+++ b/packages/core/src/routes/session/continue.test.ts
@@ -1,3 +1,4 @@
+import { PasscodeType } from '@logto/schemas';
import { addDays, subSeconds } from 'date-fns';
import { Provider } from 'oidc-provider';
@@ -138,6 +139,7 @@ describe('session -> continueRoutes', () => {
continueSignIn: {
userId: mockUser.id,
expiresAt: getTomorrowIsoString(),
+ type: PasscodeType.Continue,
},
},
});
@@ -169,6 +171,7 @@ describe('session -> continueRoutes', () => {
continueSignIn: {
userId: mockUser.id,
expiresAt: getTomorrowIsoString(),
+ type: PasscodeType.Continue,
},
},
});
diff --git a/packages/core/src/routes/session/continue.ts b/packages/core/src/routes/session/continue.ts
index a37738fd5..83d42d851 100644
--- a/packages/core/src/routes/session/continue.ts
+++ b/packages/core/src/routes/session/continue.ts
@@ -17,7 +17,7 @@ import {
import assertThat from '@/utils/assert-that';
import type { AnonymousRouter } from '../types';
-import { emailSessionResultGuard, smsSessionResultGuard } from './types';
+import { continueEmailSessionResultGuard, continueSmsSessionResultGuard } from './types';
import {
checkRequiredProfile,
getContinueSignInResult,
@@ -104,7 +104,7 @@ export default function continueRoutes(router: T, pro
const { email } = await getVerificationStorageFromInteraction(
ctx,
provider,
- emailSessionResultGuard
+ continueEmailSessionResultGuard
);
const user = await findUserById(userId);
@@ -138,7 +138,7 @@ export default function continueRoutes(router: T, pro
const { phone } = await getVerificationStorageFromInteraction(
ctx,
provider,
- smsSessionResultGuard
+ continueSmsSessionResultGuard
);
const user = await findUserById(userId);
diff --git a/packages/core/src/routes/session/passwordless.ts b/packages/core/src/routes/session/passwordless.ts
index c038f560d..e2f1686c0 100644
--- a/packages/core/src/routes/session/passwordless.ts
+++ b/packages/core/src/routes/session/passwordless.ts
@@ -117,13 +117,21 @@ export default function passwordlessRoutes(
return next();
}
- await assignVerificationResult(ctx, provider, { flow, phone });
-
if (flow === PasscodeType.SignIn) {
+ await assignVerificationResult(ctx, provider, { flow, phone });
+
return smsSignInAction(provider)(ctx, next);
}
- return smsRegisterAction(provider)(ctx, next);
+ if (flow === PasscodeType.Register) {
+ await assignVerificationResult(ctx, provider, { flow, phone });
+
+ return smsRegisterAction(provider)(ctx, next);
+ }
+
+ await assignVerificationResult(ctx, provider, { flow, phone });
+
+ return next();
}
);
@@ -161,13 +169,21 @@ export default function passwordlessRoutes(
return next();
}
- await assignVerificationResult(ctx, provider, { flow, email });
-
if (flow === PasscodeType.SignIn) {
+ await assignVerificationResult(ctx, provider, { flow, email });
+
return emailSignInAction(provider)(ctx, next);
}
- return emailRegisterAction(provider)(ctx, next);
+ if (flow === PasscodeType.Register) {
+ await assignVerificationResult(ctx, provider, { flow, email });
+
+ return emailRegisterAction(provider)(ctx, next);
+ }
+
+ await assignVerificationResult(ctx, provider, { flow, email });
+
+ return next();
}
);
diff --git a/packages/core/src/routes/session/types.ts b/packages/core/src/routes/session/types.ts
index 098b6bd0c..82469b79d 100644
--- a/packages/core/src/routes/session/types.ts
+++ b/packages/core/src/routes/session/types.ts
@@ -45,10 +45,36 @@ export const forgotPasswordSessionResultGuard = z.object({
verification: forgotPasswordSessionStorageGuard,
});
+const continueEmailSessionStorageGuard = z.object({
+ flow: z.literal(PasscodeType.Continue),
+ expiresAt: z.string(),
+ email: z.string(),
+});
+
+export type ContinueEmailSessionStorage = z.infer;
+
+export const continueEmailSessionResultGuard = z.object({
+ verification: continueEmailSessionStorageGuard,
+});
+
+const continueSmsSessionStorageGuard = z.object({
+ flow: z.literal(PasscodeType.Continue),
+ expiresAt: z.string(),
+ phone: z.string(),
+});
+
+export type ContinueSmsSessionStorage = z.infer;
+
+export const continueSmsSessionResultGuard = z.object({
+ verification: continueSmsSessionStorageGuard,
+});
+
export type VerificationStorage =
| SmsSessionStorage
| EmailSessionStorage
- | ForgotPasswordSessionStorage;
+ | ForgotPasswordSessionStorage
+ | ContinueEmailSessionStorage
+ | ContinueSmsSessionStorage;
export type VerificationResult = { verification: T };
diff --git a/packages/phrases/src/locales/de/translation/admin-console/connector-details.ts b/packages/phrases/src/locales/de/translation/admin-console/connector-details.ts
index 4a67369ad..23f210699 100644
--- a/packages/phrases/src/locales/de/translation/admin-console/connector-details.ts
+++ b/packages/phrases/src/locales/de/translation/admin-console/connector-details.ts
@@ -17,6 +17,8 @@ const connector_details = {
type_email: 'E-Mail connector',
type_sms: 'SMS connector',
type_social: 'Social connector',
+ in_use_deletion_description:
+ 'This connector is in use in your sign in experience. By deleting, sign in experience will be deleted in sign in experience settings.', // UNTRANSLATED
};
export default connector_details;
diff --git a/packages/phrases/src/locales/en/translation/admin-console/connector-details.ts b/packages/phrases/src/locales/en/translation/admin-console/connector-details.ts
index d009e9bc1..abef0e54e 100644
--- a/packages/phrases/src/locales/en/translation/admin-console/connector-details.ts
+++ b/packages/phrases/src/locales/en/translation/admin-console/connector-details.ts
@@ -17,6 +17,8 @@ const connector_details = {
type_email: 'Email connector',
type_sms: 'SMS connector',
type_social: 'Social connector',
+ in_use_deletion_description:
+ 'This connector is in use in your sign in experience. By deleting, sign in experience will be deleted in sign in experience settings.',
};
export default connector_details;
diff --git a/packages/phrases/src/locales/fr/translation/admin-console/connector-details.ts b/packages/phrases/src/locales/fr/translation/admin-console/connector-details.ts
index 4e77dea47..f11ada084 100644
--- a/packages/phrases/src/locales/fr/translation/admin-console/connector-details.ts
+++ b/packages/phrases/src/locales/fr/translation/admin-console/connector-details.ts
@@ -17,6 +17,8 @@ const connector_details = {
type_email: 'Connecteur Email',
type_sms: 'Connecteur SMS',
type_social: 'Connecteur Social',
+ in_use_deletion_description:
+ 'This connector is in use in your sign in experience. By deleting, sign in experience will be deleted in sign in experience settings.', // UNTRANSLATED
};
export default connector_details;
diff --git a/packages/phrases/src/locales/ko/translation/admin-console/connector-details.ts b/packages/phrases/src/locales/ko/translation/admin-console/connector-details.ts
index 5ea485c8e..0d0f07949 100644
--- a/packages/phrases/src/locales/ko/translation/admin-console/connector-details.ts
+++ b/packages/phrases/src/locales/ko/translation/admin-console/connector-details.ts
@@ -17,6 +17,8 @@ const connector_details = {
type_email: '이메일 연동',
type_sms: 'SMS 연동',
type_social: '소셜 연동',
+ in_use_deletion_description:
+ 'This connector is in use in your sign in experience. By deleting, sign in experience will be deleted in sign in experience settings.', // UNTRANSLATED
};
export default connector_details;
diff --git a/packages/phrases/src/locales/pt-pt/translation/admin-console/connector-details.ts b/packages/phrases/src/locales/pt-pt/translation/admin-console/connector-details.ts
index 3933d3f3c..2c081c494 100644
--- a/packages/phrases/src/locales/pt-pt/translation/admin-console/connector-details.ts
+++ b/packages/phrases/src/locales/pt-pt/translation/admin-console/connector-details.ts
@@ -17,6 +17,8 @@ const connector_details = {
type_email: 'Conector de Email',
type_sms: 'Conector de SMS',
type_social: 'Conector Social',
+ in_use_deletion_description:
+ 'This connector is in use in your sign in experience. By deleting, sign in experience will be deleted in sign in experience settings.', // UNTRANSLATED
};
export default connector_details;
diff --git a/packages/phrases/src/locales/tr-tr/translation/admin-console/connector-details.ts b/packages/phrases/src/locales/tr-tr/translation/admin-console/connector-details.ts
index b61ac449a..1730766b1 100644
--- a/packages/phrases/src/locales/tr-tr/translation/admin-console/connector-details.ts
+++ b/packages/phrases/src/locales/tr-tr/translation/admin-console/connector-details.ts
@@ -17,6 +17,8 @@ const connector_details = {
type_email: 'Eposta connectorı',
type_sms: 'SMS connectorı',
type_social: 'Social connector',
+ in_use_deletion_description:
+ 'This connector is in use in your sign in experience. By deleting, sign in experience will be deleted in sign in experience settings.', // UNTRANSLATED
};
export default connector_details;
diff --git a/packages/phrases/src/locales/zh-cn/translation/admin-console/connector-details.ts b/packages/phrases/src/locales/zh-cn/translation/admin-console/connector-details.ts
index b491d749b..2721849d8 100644
--- a/packages/phrases/src/locales/zh-cn/translation/admin-console/connector-details.ts
+++ b/packages/phrases/src/locales/zh-cn/translation/admin-console/connector-details.ts
@@ -17,6 +17,8 @@ const connector_details = {
type_email: '邮件连接器',
type_sms: '短信连接器',
type_social: '社交连接器',
+ in_use_deletion_description:
+ 'This connector is in use in your sign in experience. By deleting, sign in experience will be deleted in sign in experience settings.', // UNTRANSLATED
};
export default connector_details;
diff --git a/packages/schemas/alterations/next-1667900481-add-passcode-type-continue.ts b/packages/schemas/alterations/next-1667900481-add-passcode-type-continue.ts
new file mode 100644
index 000000000..1aa07480c
--- /dev/null
+++ b/packages/schemas/alterations/next-1667900481-add-passcode-type-continue.ts
@@ -0,0 +1,19 @@
+import { sql } from 'slonik';
+
+import type { AlterationScript } from '../lib/types/alteration';
+
+const alteration: AlterationScript = {
+ up: async (pool) => {
+ await pool.query(sql`
+ alter type passcode_type add value 'Continue'
+ `);
+ },
+ down: async (pool) => {
+ await pool.query(sql`
+ drop type passcode_type
+ create type passcode_type as enum ('SignIn', 'Register', 'ForgotPassword');
+ `);
+ },
+};
+
+export default alteration;
diff --git a/packages/schemas/tables/passcodes.sql b/packages/schemas/tables/passcodes.sql
index 300f5fd98..d596747d8 100644
--- a/packages/schemas/tables/passcodes.sql
+++ b/packages/schemas/tables/passcodes.sql
@@ -1,4 +1,4 @@
-create type passcode_type as enum ('SignIn', 'Register', 'ForgotPassword');
+create type passcode_type as enum ('SignIn', 'Register', 'ForgotPassword', 'Continue');
create table passcodes (
id varchar(21) not null,