mirror of
https://github.com/logto-io/logto.git
synced 2025-03-31 22:51:25 -05:00
feat(core): use PUT instead of POST and refactor code
This commit is contained in:
parent
7c4019b408
commit
92a04f08bd
37 changed files with 96 additions and 226 deletions
|
@ -92,16 +92,27 @@ export const isGuardMiddleware = <Type extends IMiddleware>(
|
|||
): function_ is WithGuardConfig<Type> =>
|
||||
function_.name === 'guardMiddleware' && has(function_, 'config');
|
||||
|
||||
export const tryParse = <Output, Definition extends ZodTypeDef, Input>(
|
||||
export const parse = <Output, Definition extends ZodTypeDef, Input>(
|
||||
type: 'query' | 'body' | 'params' | 'files',
|
||||
guard: ZodType<Output, Definition, Input>,
|
||||
data: unknown
|
||||
) => {
|
||||
try {
|
||||
return guard.parse(data);
|
||||
} catch (error: unknown) {
|
||||
throw new RequestError({ code: 'guard.invalid_input', type }, error);
|
||||
}
|
||||
};
|
||||
|
||||
const tryParse = <Output, Definition extends ZodTypeDef, Input>(
|
||||
type: 'query' | 'body' | 'params' | 'files',
|
||||
guard: Optional<ZodType<Output, Definition, Input>>,
|
||||
data: unknown
|
||||
) => {
|
||||
try {
|
||||
return guard?.parse(data);
|
||||
} catch (error: unknown) {
|
||||
throw new RequestError({ code: 'guard.invalid_input', type }, error);
|
||||
if (!guard) {
|
||||
return;
|
||||
}
|
||||
return parse(type, guard, data);
|
||||
};
|
||||
|
||||
export default function koaGuard<
|
||||
|
|
|
@ -53,7 +53,7 @@ export const createLogtoConfigQueries = (pool: CommonQueryMethods) => {
|
|||
`);
|
||||
|
||||
// Can not narrow down the type of value if we utilize `buildInsertIntoWithPool` method.
|
||||
const insertJwtCustomizer = async <T extends LogtoJwtTokenKey>(
|
||||
const insertOrUpdateJwtCustomizer = async <T extends LogtoJwtTokenKey>(
|
||||
key: T,
|
||||
value: z.infer<(typeof jwtCustomizerConfigGuard)[T]>
|
||||
) =>
|
||||
|
@ -61,7 +61,9 @@ export const createLogtoConfigQueries = (pool: CommonQueryMethods) => {
|
|||
sql`
|
||||
insert into ${table} (${fields.key}, ${fields.value})
|
||||
values (${key}, ${sql.jsonb(value)})
|
||||
on conflict (${fields.tenantId}, ${fields.key}) do nothing
|
||||
on conflict (${fields.tenantId}, ${fields.key}) do update set ${
|
||||
fields.value
|
||||
} = ${sql.jsonb(value)}
|
||||
returning *
|
||||
`
|
||||
);
|
||||
|
@ -72,6 +74,6 @@ export const createLogtoConfigQueries = (pool: CommonQueryMethods) => {
|
|||
getCloudConnectionData,
|
||||
getRowsByKeys,
|
||||
updateOidcConfigsByKey,
|
||||
insertJwtCustomizer,
|
||||
insertOrUpdateJwtCustomizer,
|
||||
};
|
||||
};
|
||||
|
|
|
@ -106,9 +106,9 @@
|
|||
}
|
||||
},
|
||||
"/api/configs/jwt-customizer/{tokenType}": {
|
||||
"post": {
|
||||
"summary": "Create JWT customizer",
|
||||
"description": "Create a JWT customizer for the given token type.",
|
||||
"put": {
|
||||
"summary": "Create or update JWT customizer",
|
||||
"description": "Create or update a JWT customizer for the given token type.",
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
|
@ -139,14 +139,14 @@
|
|||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The updated JWT customizer."
|
||||
},
|
||||
"201": {
|
||||
"description": "The created JWT customizer."
|
||||
},
|
||||
"400": {
|
||||
"description": "The request body is invalid."
|
||||
},
|
||||
"409": {
|
||||
"description": "The JWT customizer already exists."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ const logtoConfigQueries = {
|
|||
}),
|
||||
updateOidcConfigsByKey: jest.fn(),
|
||||
getRowsByKeys: jest.fn(async () => mockLogtoConfigRows),
|
||||
insertJwtCustomizer: jest.fn(),
|
||||
insertOrUpdateJwtCustomizer: jest.fn(),
|
||||
};
|
||||
|
||||
const logtoConfigLibraries = {
|
||||
|
@ -226,36 +226,43 @@ describe('configs routes', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('POST /configs/jwt-customizer/:tokenType should add a record successfully', async () => {
|
||||
it('PUT /configs/jwt-customizer/:tokenType should add a record successfully', async () => {
|
||||
logtoConfigQueries.getRowsByKeys.mockResolvedValueOnce({
|
||||
...mockLogtoConfigRows,
|
||||
rows: [],
|
||||
rowCount: 0,
|
||||
});
|
||||
logtoConfigQueries.insertJwtCustomizer.mockResolvedValueOnce(
|
||||
logtoConfigQueries.insertOrUpdateJwtCustomizer.mockResolvedValueOnce(
|
||||
mockJwtCustomizerConfigForAccessToken
|
||||
);
|
||||
const response = await routeRequester
|
||||
.post('/configs/jwt-customizer/access-token')
|
||||
.send(mockJwtCustomizerConfigForAccessToken);
|
||||
expect(logtoConfigQueries.insertJwtCustomizer).toHaveBeenCalledWith(
|
||||
.put(`/configs/jwt-customizer/access-token`)
|
||||
.send(mockJwtCustomizerConfigForAccessToken.value);
|
||||
expect(logtoConfigQueries.insertOrUpdateJwtCustomizer).toHaveBeenCalledWith(
|
||||
LogtoJwtTokenKey.AccessToken,
|
||||
mockJwtCustomizerConfigForAccessToken
|
||||
mockJwtCustomizerConfigForAccessToken.value
|
||||
);
|
||||
expect(response.status).toEqual(201);
|
||||
expect(response.body).toEqual(mockJwtCustomizerConfigForAccessToken.value);
|
||||
});
|
||||
|
||||
it('POST /configs/jwt-customizer/:tokenType should fail ', async () => {
|
||||
it('PUT /configs/jwt-customizer/:tokenType should update a record successfully', async () => {
|
||||
logtoConfigQueries.getRowsByKeys.mockResolvedValueOnce({
|
||||
...mockLogtoConfigRows,
|
||||
rows: [mockJwtCustomizerConfigForAccessToken],
|
||||
rowCount: 1,
|
||||
});
|
||||
logtoConfigQueries.insertOrUpdateJwtCustomizer.mockResolvedValueOnce(
|
||||
mockJwtCustomizerConfigForAccessToken
|
||||
);
|
||||
const response = await routeRequester
|
||||
.post('/configs/jwt-customizer/access-token')
|
||||
.send(mockJwtCustomizerConfigForAccessToken);
|
||||
expect(logtoConfigQueries.insertJwtCustomizer).not.toHaveBeenCalled();
|
||||
expect(response.status).toEqual(409);
|
||||
.put('/configs/jwt-customizer/access-token')
|
||||
.send(mockJwtCustomizerConfigForAccessToken.value);
|
||||
expect(logtoConfigQueries.insertOrUpdateJwtCustomizer).toHaveBeenCalledWith(
|
||||
LogtoJwtTokenKey.AccessToken,
|
||||
mockJwtCustomizerConfigForAccessToken.value
|
||||
);
|
||||
expect(response.status).toEqual(200);
|
||||
expect(response.body).toEqual(mockJwtCustomizerConfigForAccessToken.value);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -20,8 +20,7 @@ import {
|
|||
import { z } from 'zod';
|
||||
|
||||
import RequestError from '#src/errors/RequestError/index.js';
|
||||
import koaGuard, { tryParse } from '#src/middleware/koa-guard.js';
|
||||
import assertThat from '#src/utils/assert-that.js';
|
||||
import koaGuard, { parse } from '#src/middleware/koa-guard.js';
|
||||
import { exportJWK } from '#src/utils/jwks.js';
|
||||
|
||||
import type { AuthedRouter, RouterInitArgs } from './types.js';
|
||||
|
@ -39,6 +38,16 @@ const getLogtoJwtTokenKey = (key: LogtoJwtTokenKeyType): LogtoJwtTokenKey =>
|
|||
? LogtoJwtTokenKey.AccessToken
|
||||
: LogtoJwtTokenKey.ClientCredentials;
|
||||
|
||||
const guardJwtCustomizerBody = (tokenType: LogtoJwtTokenKeyType, body: unknown) => {
|
||||
// Manually implement the request body type check, the flow aligns with the actual `koaGuard()`.
|
||||
// Use ternary operator to get the specific guard brings difficulties to type inference.
|
||||
if (tokenType === LogtoJwtTokenKeyType.AccessToken) {
|
||||
return parse('body', jwtCustomizerAccessTokenGuard, body);
|
||||
}
|
||||
|
||||
return parse('body', jwtCustomizerClientCredentialsGuard, body);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove actual values of the private keys from response.
|
||||
* @param type Logto config key DB column name. Values are either `oidc.privateKeys` or `oidc.cookieKeys`.
|
||||
|
@ -73,7 +82,7 @@ export default function logtoConfigRoutes<T extends AuthedRouter>(
|
|||
const {
|
||||
getAdminConsoleConfig,
|
||||
getRowsByKeys,
|
||||
insertJwtCustomizer,
|
||||
insertOrUpdateJwtCustomizer,
|
||||
updateAdminConsoleConfig,
|
||||
updateOidcConfigsByKey,
|
||||
} = queries.logtoConfigs;
|
||||
|
@ -198,7 +207,7 @@ export default function logtoConfigRoutes<T extends AuthedRouter>(
|
|||
}
|
||||
);
|
||||
|
||||
router.post(
|
||||
router.put(
|
||||
'/configs/jwt-customizer/:tokenType',
|
||||
koaGuard({
|
||||
params: z.object({
|
||||
|
@ -208,43 +217,28 @@ export default function logtoConfigRoutes<T extends AuthedRouter>(
|
|||
* Use `z.unknown()` to guard the request body as a JSON object, since the actual guard depends
|
||||
* on the `tokenType` and we can not get the value of `tokenType` before parsing the request body,
|
||||
* we will do more specific guard as long as we can get the value of `tokenType`.
|
||||
*
|
||||
* Should specify `body` in koaGuard, otherwise the request body is not accessible even via `ctx.request.body`.
|
||||
*/
|
||||
body: z.unknown(),
|
||||
response: jwtCustomizerAccessTokenGuard.or(jwtCustomizerClientCredentialsGuard),
|
||||
status: [201, 400, 409],
|
||||
status: [200, 201, 400],
|
||||
}),
|
||||
async (ctx, next) => {
|
||||
const {
|
||||
params: { tokenType },
|
||||
body,
|
||||
body: rawBody,
|
||||
} = ctx.guard;
|
||||
const key = getLogtoJwtTokenKey(tokenType);
|
||||
const body = guardJwtCustomizerBody(tokenType, rawBody);
|
||||
|
||||
// Manually implement the request body type check, the flow aligns with the actual `koaGuard()`.
|
||||
// Use ternary operator to get the specific guard brings difficulties to type inference.
|
||||
if (tokenType === LogtoJwtTokenKeyType.AccessToken) {
|
||||
tryParse('body', jwtCustomizerAccessTokenGuard, body);
|
||||
} else {
|
||||
tryParse('body', jwtCustomizerClientCredentialsGuard, body);
|
||||
const { rows } = await getRowsByKeys([key]);
|
||||
|
||||
const jwtCustomizer = await insertOrUpdateJwtCustomizer(key, body);
|
||||
|
||||
if (rows.length === 0) {
|
||||
ctx.status = 201;
|
||||
}
|
||||
|
||||
const { rows } = await getRowsByKeys([getLogtoJwtTokenKey(tokenType)]);
|
||||
assertThat(
|
||||
rows.length === 0,
|
||||
new RequestError({
|
||||
code: 'logto_config.jwt.customizer_exists',
|
||||
tokenType,
|
||||
status: 409,
|
||||
})
|
||||
);
|
||||
|
||||
const jwtCustomizer = await insertJwtCustomizer(
|
||||
getLogtoJwtTokenKey(tokenType),
|
||||
// Since we applied the detailed guard manually, we can safely cast the `body` to the specific type.
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
body as Parameters<typeof insertJwtCustomizer>[1]
|
||||
);
|
||||
|
||||
ctx.status = 201;
|
||||
ctx.body = jwtCustomizer.value;
|
||||
|
||||
return next();
|
||||
|
|
|
@ -34,7 +34,7 @@ export const rotateOidcKeys = async (
|
|||
.post(`configs/oidc/${keyType}/rotate`, { json: { signingKeyAlgorithm } })
|
||||
.json<OidcConfigKeysResponse[]>();
|
||||
|
||||
export const insertJwtCustomizer = async (keyType: LogtoJwtTokenKeyType, value: unknown) =>
|
||||
export const insertOrUpdateJwtCustomizer = async (keyType: LogtoJwtTokenKeyType, value: unknown) =>
|
||||
authedAdminApi
|
||||
.post(`configs/jwt-customizer/${keyType}`, { json: value })
|
||||
.put(`configs/jwt-customizer/${keyType}`, { json: value })
|
||||
.json<JwtCustomizerAccessToken | JwtCustomizerClientCredentials>();
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
getOidcKeys,
|
||||
rotateOidcKeys,
|
||||
updateAdminConsoleConfig,
|
||||
insertJwtCustomizer,
|
||||
insertOrUpdateJwtCustomizer,
|
||||
} from '#src/api/index.js';
|
||||
import { expectRejects } from '#src/helpers/index.js';
|
||||
|
||||
|
@ -141,15 +141,35 @@ describe('admin console sign-in experience', () => {
|
|||
...accessTokenJwtCustomizerPayload,
|
||||
contextSample: {},
|
||||
};
|
||||
const accessToken = await insertJwtCustomizer(
|
||||
|
||||
const accessToken = await insertOrUpdateJwtCustomizer(
|
||||
LogtoJwtTokenKeyType.AccessToken,
|
||||
accessTokenJwtCustomizerPayload
|
||||
);
|
||||
expect(accessToken).toMatchObject(accessTokenJwtCustomizerPayload);
|
||||
const clientCredentials = await insertJwtCustomizer(
|
||||
const newAccessTokenJwtCustomizerPayload = {
|
||||
...accessTokenJwtCustomizerPayload,
|
||||
script: 'new script',
|
||||
};
|
||||
const updatedAccessToken = await insertOrUpdateJwtCustomizer(
|
||||
LogtoJwtTokenKeyType.AccessToken,
|
||||
newAccessTokenJwtCustomizerPayload
|
||||
);
|
||||
expect(updatedAccessToken).toMatchObject(newAccessTokenJwtCustomizerPayload);
|
||||
|
||||
const clientCredentials = await insertOrUpdateJwtCustomizer(
|
||||
LogtoJwtTokenKeyType.ClientCredentials,
|
||||
clientCredentialsJwtCustomizerPayload
|
||||
);
|
||||
expect(clientCredentials).toMatchObject(clientCredentialsJwtCustomizerPayload);
|
||||
const newClientCredentialsJwtCustomizerPayload = {
|
||||
...clientCredentialsJwtCustomizerPayload,
|
||||
script: 'new script client credentials',
|
||||
};
|
||||
const updatedClientCredentials = await insertOrUpdateJwtCustomizer(
|
||||
LogtoJwtTokenKeyType.ClientCredentials,
|
||||
newClientCredentialsJwtCustomizerPayload
|
||||
);
|
||||
expect(updatedClientCredentials).toMatchObject(newClientCredentialsJwtCustomizerPayload);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
|
@ -7,7 +7,6 @@ import guard from './guard.js';
|
|||
import hook from './hook.js';
|
||||
import localization from './localization.js';
|
||||
import log from './log.js';
|
||||
import logto_config from './logto-config.js';
|
||||
import oidc from './oidc.js';
|
||||
import organization from './organization.js';
|
||||
import password from './password.js';
|
||||
|
@ -36,7 +35,6 @@ const errors = {
|
|||
verification_code,
|
||||
sign_in_experiences,
|
||||
localization,
|
||||
logto_config,
|
||||
swagger,
|
||||
entity,
|
||||
log,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
const logto_config = {
|
||||
jwt: {
|
||||
/** UNTRANSLATED */
|
||||
customizer_exists:
|
||||
'Can not create a new customizer since there is already one for the token type `{{tokenType}}`.',
|
||||
},
|
||||
};
|
||||
|
||||
export default Object.freeze(logto_config);
|
Loading…
Add table
Reference in a new issue