mirror of
https://github.com/logto-io/logto.git
synced 2024-12-30 20:33:54 -05:00
feat(core): put invitation status
This commit is contained in:
parent
2e31b976ca
commit
0a20b5a6f8
22 changed files with 530 additions and 147 deletions
|
@ -60,7 +60,7 @@
|
|||
"@microsoft/applicationinsights-clickanalytics-js": "^3.0.2",
|
||||
"@microsoft/applicationinsights-react-js": "^17.0.0",
|
||||
"@microsoft/applicationinsights-web": "^3.0.2",
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"applicationinsights": "^2.7.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
"@logto/phrases-experience": "workspace:^1.5.0",
|
||||
"@logto/schemas": "workspace:1.12.0",
|
||||
"@logto/shared": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"chalk": "^5.0.0",
|
||||
"decamelize": "^6.0.0",
|
||||
"dotenv": "^16.0.0",
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
"prepublishOnly": "pnpm build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"got": "^14.0.0",
|
||||
"snakecase-keys": "^5.4.4",
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
"@parcel/transformer-svg-react": "2.9.3",
|
||||
"@silverhand/eslint-config": "5.0.0",
|
||||
"@silverhand/eslint-config-react": "5.0.0",
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"@silverhand/ts-config": "5.0.0",
|
||||
"@silverhand/ts-config-react": "5.0.0",
|
||||
"@swc/core": "^1.3.52",
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
"@logto/phrases-experience": "workspace:^1.5.0",
|
||||
"@logto/schemas": "workspace:^1.12.0",
|
||||
"@logto/shared": "workspace:^3.0.0",
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"@simplewebauthn/server": "^8.2.0",
|
||||
"@withtyped/client": "^0.7.22",
|
||||
"camelcase": "^8.0.0",
|
||||
|
|
|
@ -1,18 +1,34 @@
|
|||
import { ConnectorType, TemplateType } from '@logto/connector-kit';
|
||||
import { OrganizationInvitationStatus, type CreateOrganizationInvitation } from '@logto/schemas';
|
||||
import {
|
||||
OrganizationInvitationStatus,
|
||||
type CreateOrganizationInvitation,
|
||||
type OrganizationInvitationEntity,
|
||||
} from '@logto/schemas';
|
||||
import { generateStandardId } from '@logto/shared';
|
||||
import { appendPath } from '@silverhand/essentials';
|
||||
import { appendPath, removeUndefinedKeys } from '@silverhand/essentials';
|
||||
|
||||
import { EnvSet } from '#src/env-set/index.js';
|
||||
import { getTenantEndpoint } from '#src/env-set/utils.js';
|
||||
import RequestError from '#src/errors/RequestError/index.js';
|
||||
import MagicLinkQueries from '#src/queries/magic-link.js';
|
||||
import OrganizationQueries from '#src/queries/organization/index.js';
|
||||
import { createUserQueries } from '#src/queries/user.js';
|
||||
import type Queries from '#src/tenants/Queries.js';
|
||||
|
||||
import { type ConnectorLibrary } from './connector.js';
|
||||
|
||||
const invitationLinkPath = '/invitation';
|
||||
|
||||
/**
|
||||
* The ending statuses of an organization invitation per RFC 0003. It means that the invitation
|
||||
* status cannot be changed anymore.
|
||||
*/
|
||||
const endingStatuses = Object.freeze([
|
||||
OrganizationInvitationStatus.Accepted,
|
||||
OrganizationInvitationStatus.Expired,
|
||||
OrganizationInvitationStatus.Revoked,
|
||||
]);
|
||||
|
||||
/** Class for managing organization invitations. */
|
||||
export class OrganizationInvitationLibrary {
|
||||
constructor(
|
||||
|
@ -77,6 +93,108 @@ export class OrganizationInvitationLibrary {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Revokes an organization invitation. The transaction will be rolled back if the status is one
|
||||
* of the ending statuses.
|
||||
*
|
||||
* @param id The ID of the invitation.
|
||||
* @param status The new status of the invitation.
|
||||
* @returns A promise that resolves to the updated invitation.
|
||||
* @see {@link endingStatuses} for the ending statuses.
|
||||
*/
|
||||
async updateStatus(
|
||||
id: string,
|
||||
status: OrganizationInvitationStatus.Revoked
|
||||
): Promise<OrganizationInvitationEntity>;
|
||||
/**
|
||||
* Updates the status of an organization invitation to `Accepted`, and assigns the user to the
|
||||
* organization with the provided roles in the invitation.
|
||||
*
|
||||
* The transaction will be rolled back if:
|
||||
* - The status is one of the ending statuses.
|
||||
* - The `acceptedUserId` is not provided.
|
||||
* - The `acceptedUserId` is not the same as the invitee.
|
||||
*
|
||||
* @param id The ID of the invitation.
|
||||
* @param status The new status of the invitation (`Accepted`).
|
||||
* @param acceptedUserId The user ID of the user who accepted the invitation.
|
||||
* @returns A promise that resolves to the updated invitation.
|
||||
* @see {@link endingStatuses} for the ending statuses.
|
||||
*/
|
||||
async updateStatus(
|
||||
id: string,
|
||||
status: OrganizationInvitationStatus.Accepted,
|
||||
acceptedUserId: string
|
||||
): Promise<OrganizationInvitationEntity>;
|
||||
// TODO: Error i18n
|
||||
async updateStatus(
|
||||
id: string,
|
||||
status: OrganizationInvitationStatus,
|
||||
acceptedUserId?: string
|
||||
): Promise<OrganizationInvitationEntity> {
|
||||
const entity = await this.queries.organizations.invitations.findById(id);
|
||||
|
||||
if (endingStatuses.includes(entity.status)) {
|
||||
throw new RequestError({
|
||||
status: 422,
|
||||
code: 'request.invalid_input',
|
||||
details: 'The status of the invitation cannot be changed anymore.',
|
||||
});
|
||||
}
|
||||
|
||||
return this.queries.pool.transaction(async (connection) => {
|
||||
const organizationQueries = new OrganizationQueries(connection);
|
||||
const userQueries = createUserQueries(connection);
|
||||
|
||||
switch (status) {
|
||||
case OrganizationInvitationStatus.Accepted: {
|
||||
// Normally this shouldn't happen, so we use `TypeError` instead of `RequestError`.
|
||||
if (!acceptedUserId) {
|
||||
throw new TypeError('The `acceptedUserId` is required when accepting an invitation.');
|
||||
}
|
||||
|
||||
const user = await userQueries.findUserById(acceptedUserId);
|
||||
|
||||
if (user.primaryEmail !== entity.invitee) {
|
||||
throw new RequestError({
|
||||
status: 422,
|
||||
code: 'request.invalid_input',
|
||||
details: 'The accepted user must have the same email as the invitee.',
|
||||
});
|
||||
}
|
||||
|
||||
await organizationQueries.relations.users.insert([entity.organizationId, acceptedUserId]);
|
||||
|
||||
if (entity.organizationRoles.length > 0) {
|
||||
await organizationQueries.relations.rolesUsers.insert(
|
||||
...entity.organizationRoles.map<[string, string, string]>((role) => [
|
||||
entity.organizationId,
|
||||
role.id,
|
||||
acceptedUserId,
|
||||
])
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OrganizationInvitationStatus.Revoked: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new TypeError(`The status "${status}" is not supported.`);
|
||||
}
|
||||
}
|
||||
|
||||
const updated = {
|
||||
status,
|
||||
acceptedUserId,
|
||||
updatedAt: Date.now(),
|
||||
};
|
||||
await organizationQueries.invitations.updateById(id, updated);
|
||||
|
||||
return { ...entity, ...removeUndefinedKeys(updated) };
|
||||
});
|
||||
}
|
||||
|
||||
protected async sendEmail(to: string, token: string) {
|
||||
const emailConnector = await this.connector.getMessageConnector(ConnectorType.Email);
|
||||
return emailConnector.sendMessage({
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
type OrganizationInvitationEntity,
|
||||
MagicLinks,
|
||||
OrganizationInvitationRoleRelations,
|
||||
OrganizationInvitationStatus,
|
||||
} from '@logto/schemas';
|
||||
import { conditionalSql, convertToIdentifiers } from '@logto/shared';
|
||||
import { sql, type CommonQueryMethods } from 'slonik';
|
||||
|
@ -121,7 +122,19 @@ class OrganizationInvitationsQueries extends SchemaQueries<
|
|||
|
||||
return sql<OrganizationInvitationEntity>`
|
||||
select
|
||||
${table}.*,
|
||||
${sql.join(
|
||||
Object.values(fields).filter((field) => field !== fields.status),
|
||||
sql`, `
|
||||
)},
|
||||
-- Dynamically calculate the status of the invitation, note that the
|
||||
-- actual status of the invitation is not changed.
|
||||
case
|
||||
when
|
||||
${fields.status} = ${OrganizationInvitationStatus.Pending} and
|
||||
${fields.expiresAt} < now()
|
||||
then ${OrganizationInvitationStatus.Expired}
|
||||
else ${fields.status}
|
||||
end as "status",
|
||||
coalesce(
|
||||
json_agg(
|
||||
json_build_object(
|
||||
|
|
|
@ -72,17 +72,6 @@
|
|||
"get": {
|
||||
"summary": "Get organization invitation",
|
||||
"description": "Get an organization invitation by ID.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"description": "The organization invitation ID.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The organization invitation, also contains the organization roles to be assigned to the user when they accept the invitation, and the corresponding magic link data."
|
||||
|
@ -92,23 +81,41 @@
|
|||
"delete": {
|
||||
"summary": "Delete organization invitation",
|
||||
"description": "Delete an organization invitation by ID.",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"description": "The organization invitation ID.",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "The organization invitation was deleted successfully."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/organization-invitations/{id}/status": {
|
||||
"put": {
|
||||
"summary": "Update organization invitation status",
|
||||
"description": "Update the status of an organization invitation by ID.",
|
||||
"requestBody": {
|
||||
"description": "The organization invitation status to update.",
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"properties": {
|
||||
"status": {
|
||||
"description": "The status of the organization invitation."
|
||||
},
|
||||
"acceptedUserId": {
|
||||
"description": "The ID of the user who accepted the organization invitation. Required if the status is \"Accepted\"."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "The organization invitation status was updated successfully."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { OrganizationInvitations, organizationInvitationEntityGuard } from '@logto/schemas';
|
||||
import {
|
||||
OrganizationInvitationStatus,
|
||||
OrganizationInvitations,
|
||||
organizationInvitationEntityGuard,
|
||||
} from '@logto/schemas';
|
||||
import { yes } from '@silverhand/essentials';
|
||||
import { z } from 'zod';
|
||||
|
||||
|
@ -51,7 +55,7 @@ export default function organizationInvitationRoutes<T extends AuthedRouter>(
|
|||
response: organizationInvitationEntityGuard,
|
||||
status: [201],
|
||||
}),
|
||||
async (ctx) => {
|
||||
async (ctx, next) => {
|
||||
const { query, body } = ctx.guard;
|
||||
|
||||
assertThat(
|
||||
|
@ -64,6 +68,50 @@ export default function organizationInvitationRoutes<T extends AuthedRouter>(
|
|||
|
||||
ctx.body = await organizationInvitations.insert(body, yes(query.skipEmail));
|
||||
ctx.status = 201;
|
||||
return next();
|
||||
}
|
||||
);
|
||||
|
||||
router.put(
|
||||
'/:id/status',
|
||||
koaGuard({
|
||||
params: z.object({
|
||||
id: z.string(),
|
||||
}),
|
||||
body: OrganizationInvitations.updateGuard
|
||||
.pick({
|
||||
acceptedUserId: true,
|
||||
})
|
||||
.extend({
|
||||
status: z.enum([
|
||||
OrganizationInvitationStatus.Accepted,
|
||||
OrganizationInvitationStatus.Revoked,
|
||||
]),
|
||||
}),
|
||||
response: organizationInvitationEntityGuard,
|
||||
status: [200],
|
||||
}),
|
||||
async (ctx, next) => {
|
||||
const { id } = ctx.guard.params;
|
||||
const { status, acceptedUserId } = ctx.guard.body;
|
||||
|
||||
if (status !== OrganizationInvitationStatus.Accepted) {
|
||||
ctx.body = await organizationInvitations.updateStatus(id, status);
|
||||
return next();
|
||||
}
|
||||
|
||||
// TODO: Error i18n
|
||||
assertThat(
|
||||
acceptedUserId,
|
||||
new RequestError({
|
||||
status: 422,
|
||||
code: 'request.invalid_input',
|
||||
details: 'The `acceptedUserId` is required when accepting an invitation.',
|
||||
})
|
||||
);
|
||||
|
||||
ctx.body = await organizationInvitations.updateStatus(id, status, acceptedUserId);
|
||||
return next();
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
"@react-spring/web": "^9.6.1",
|
||||
"@silverhand/eslint-config": "5.0.0",
|
||||
"@silverhand/eslint-config-react": "5.0.0",
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"@silverhand/ts-config": "5.0.0",
|
||||
"@silverhand/ts-config-react": "5.0.0",
|
||||
"@simplewebauthn/browser": "^8.3.1",
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
"@logto/schemas": "workspace:^1.12.0",
|
||||
"@logto/shared": "workspace:^3.0.0",
|
||||
"@silverhand/eslint-config": "5.0.0",
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"@silverhand/ts-config": "5.0.0",
|
||||
"@types/jest": "^29.4.0",
|
||||
"@types/node": "^20.9.5",
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
import { type OrganizationInvitationEntity } from '@logto/schemas';
|
||||
import {
|
||||
type OrganizationInvitationStatus,
|
||||
type OrganizationInvitationEntity,
|
||||
} from '@logto/schemas';
|
||||
|
||||
import { authedAdminApi } from './api.js';
|
||||
import { ApiFactory } from './factory.js';
|
||||
|
@ -29,4 +32,15 @@ export class OrganizationInvitationApi extends ApiFactory<
|
|||
})
|
||||
.json<OrganizationInvitationEntity>();
|
||||
}
|
||||
|
||||
async updateStatus(id: string, status: OrganizationInvitationStatus, acceptedUserId?: string) {
|
||||
return authedAdminApi
|
||||
.put(`${this.path}/${id}/status`, {
|
||||
json: {
|
||||
status,
|
||||
acceptedUserId,
|
||||
},
|
||||
})
|
||||
.json<OrganizationInvitationEntity>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ const expectErrorResponse = (error: unknown, status: number, code: string) => {
|
|||
expect(body).toMatchObject({ code });
|
||||
};
|
||||
|
||||
describe('organization invitations', () => {
|
||||
describe('organization invitation creation', () => {
|
||||
const invitationApi = new OrganizationInvitationApiTest();
|
||||
const organizationApi = new OrganizationApiTest();
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
import assert from 'node:assert';
|
||||
|
||||
import { OrganizationInvitationStatus } from '@logto/schemas';
|
||||
import { generateStandardId } from '@logto/shared';
|
||||
import { HTTPError } from 'got';
|
||||
|
||||
import { OrganizationApiTest, OrganizationInvitationApiTest } from '#src/helpers/organization.js';
|
||||
import { UserApiTest } from '#src/helpers/user.js';
|
||||
|
||||
const randomId = () => generateStandardId(4);
|
||||
|
||||
const expectErrorResponse = (error: unknown, status: number, code: string) => {
|
||||
assert(error instanceof HTTPError);
|
||||
const { statusCode, body: raw } = error.response;
|
||||
const body: unknown = JSON.parse(String(raw));
|
||||
expect(statusCode).toBe(status);
|
||||
expect(body).toMatchObject({ code });
|
||||
};
|
||||
|
||||
describe('organization invitation status update', () => {
|
||||
const invitationApi = new OrganizationInvitationApiTest();
|
||||
const organizationApi = new OrganizationApiTest();
|
||||
const userApi = new UserApiTest();
|
||||
|
||||
afterEach(async () => {
|
||||
await Promise.all([
|
||||
organizationApi.cleanUp(),
|
||||
organizationApi.roleApi.cleanUp(),
|
||||
invitationApi.cleanUp(),
|
||||
userApi.cleanUp(),
|
||||
]);
|
||||
});
|
||||
|
||||
it('should expire invitations and disable update after the expiration date', async () => {
|
||||
const organization = await organizationApi.create({ name: 'test' });
|
||||
const invitation = await invitationApi.create(
|
||||
{
|
||||
organizationId: organization.id,
|
||||
invitee: `${randomId()}@example.com`,
|
||||
expiresAt: Date.now() + 100,
|
||||
},
|
||||
true
|
||||
);
|
||||
expect(invitation.status).toBe('Pending');
|
||||
|
||||
await new Promise((resolve) => {
|
||||
setTimeout(resolve, 200);
|
||||
});
|
||||
|
||||
const invitationById = await invitationApi.get(invitation.id);
|
||||
expect(invitationById.status).toBe('Expired');
|
||||
|
||||
const error = await invitationApi
|
||||
.updateStatus(invitation.id, OrganizationInvitationStatus.Accepted)
|
||||
.catch((error: unknown) => error);
|
||||
expectErrorResponse(error, 422, 'request.invalid_input');
|
||||
});
|
||||
|
||||
it('should be able to accept an invitation', async () => {
|
||||
const organization = await organizationApi.create({ name: 'test' });
|
||||
const invitation = await invitationApi.create(
|
||||
{
|
||||
organizationId: organization.id,
|
||||
invitee: `${randomId()}@example.com`,
|
||||
expiresAt: Date.now() + 1_000_000,
|
||||
},
|
||||
true
|
||||
);
|
||||
expect(invitation.status).toBe('Pending');
|
||||
|
||||
const user = await userApi.create({
|
||||
primaryEmail: invitation.invitee,
|
||||
});
|
||||
const updated = await invitationApi.updateStatus(
|
||||
invitation.id,
|
||||
OrganizationInvitationStatus.Accepted,
|
||||
user.id
|
||||
);
|
||||
|
||||
expect(updated.status).toBe('Accepted');
|
||||
|
||||
const userOrganizations = await organizationApi.getUserOrganizations(user.id);
|
||||
expect(userOrganizations).toContainEqual(
|
||||
expect.objectContaining({
|
||||
id: organization.id,
|
||||
name: organization.name,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should be able to accept an invitation with roles', async () => {
|
||||
const organization = await organizationApi.create({ name: 'test' });
|
||||
const role = await organizationApi.roleApi.create({ name: 'test' });
|
||||
const invitation = await invitationApi.create(
|
||||
{
|
||||
organizationId: organization.id,
|
||||
invitee: `${randomId()}@example.com`,
|
||||
expiresAt: Date.now() + 1_000_000,
|
||||
organizationRoleIds: [role.id],
|
||||
},
|
||||
true
|
||||
);
|
||||
expect(invitation.status).toBe('Pending');
|
||||
|
||||
const user = await userApi.create({
|
||||
primaryEmail: invitation.invitee,
|
||||
});
|
||||
const updated = await invitationApi.updateStatus(
|
||||
invitation.id,
|
||||
OrganizationInvitationStatus.Accepted,
|
||||
user.id
|
||||
);
|
||||
|
||||
expect(updated.status).toBe('Accepted');
|
||||
|
||||
const userOrganizations = await organizationApi.getUserOrganizations(user.id);
|
||||
expect(userOrganizations).toContainEqual(
|
||||
expect.objectContaining({
|
||||
id: organization.id,
|
||||
name: organization.name,
|
||||
organizationRoles: [expect.objectContaining({ id: role.id, name: role.name })],
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should not be able to accept an invitation with a different email', async () => {
|
||||
const organization = await organizationApi.create({ name: 'test' });
|
||||
const invitation = await invitationApi.create(
|
||||
{
|
||||
organizationId: organization.id,
|
||||
invitee: `${randomId()}@example.com`,
|
||||
expiresAt: Date.now() + 1_000_000,
|
||||
},
|
||||
true
|
||||
);
|
||||
expect(invitation.status).toBe('Pending');
|
||||
|
||||
const user = await userApi.create({
|
||||
primaryEmail: `${randomId()}@example.com`,
|
||||
});
|
||||
const error = await invitationApi
|
||||
.updateStatus(invitation.id, OrganizationInvitationStatus.Accepted, user.id)
|
||||
.catch((error: unknown) => error);
|
||||
|
||||
expectErrorResponse(error, 422, 'request.invalid_input');
|
||||
});
|
||||
|
||||
it('should not be able to accept an invitation with an invalid user id', async () => {
|
||||
const organization = await organizationApi.create({ name: 'test' });
|
||||
const invitation = await invitationApi.create(
|
||||
{
|
||||
organizationId: organization.id,
|
||||
invitee: `${randomId()}@example.com`,
|
||||
expiresAt: Date.now() + 1_000_000,
|
||||
},
|
||||
true
|
||||
);
|
||||
expect(invitation.status).toBe('Pending');
|
||||
|
||||
const error = await invitationApi
|
||||
.updateStatus(invitation.id, OrganizationInvitationStatus.Accepted, 'invalid')
|
||||
.catch((error: unknown) => error);
|
||||
|
||||
expectErrorResponse(error, 404, 'entity.not_found');
|
||||
});
|
||||
|
||||
it('should not be able to update the status of an ended invitation', async () => {
|
||||
const organization = await organizationApi.create({ name: 'test' });
|
||||
const invitation = await invitationApi.create(
|
||||
{
|
||||
organizationId: organization.id,
|
||||
invitee: `${randomId()}@example.com`,
|
||||
expiresAt: Date.now() + 1_000_000,
|
||||
},
|
||||
true
|
||||
);
|
||||
expect(invitation.status).toBe('Pending');
|
||||
|
||||
await invitationApi.updateStatus(invitation.id, OrganizationInvitationStatus.Revoked);
|
||||
|
||||
const error = await invitationApi
|
||||
.updateStatus(invitation.id, OrganizationInvitationStatus.Accepted)
|
||||
.catch((error: unknown) => error);
|
||||
|
||||
expectErrorResponse(error, 422, 'request.invalid_input');
|
||||
});
|
||||
});
|
|
@ -35,7 +35,7 @@
|
|||
"dependencies": {
|
||||
"@logto/core-kit": "workspace:^2.2.1",
|
||||
"@logto/language-kit": "workspace:^1.0.0",
|
||||
"@silverhand/essentials": "^2.8.4"
|
||||
"@silverhand/essentials": "^2.8.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@logto/language-kit": "workspace:^1.0.0",
|
||||
"@silverhand/essentials": "^2.8.4"
|
||||
"@silverhand/essentials": "^2.8.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"zod": "^3.22.4"
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@silverhand/eslint-config": "5.0.0",
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"@silverhand/ts-config": "5.0.0",
|
||||
"@types/inquirer": "^9.0.0",
|
||||
"@types/jest": "^29.4.0",
|
||||
|
|
|
@ -93,12 +93,12 @@ export type OrganizationWithFeatured = Organization & {
|
|||
* - `organizationRoles`: The roles to be assigned to the user when accepting the invitation.
|
||||
*/
|
||||
export type OrganizationInvitationEntity = OrganizationInvitation & {
|
||||
magicLink: MagicLink;
|
||||
magicLink?: MagicLink;
|
||||
organizationRoles: OrganizationRoleEntity[];
|
||||
};
|
||||
|
||||
export const organizationInvitationEntityGuard: z.ZodType<OrganizationInvitationEntity> =
|
||||
OrganizationInvitations.guard.extend({
|
||||
magicLink: MagicLinks.guard,
|
||||
magicLink: MagicLinks.guard.optional(),
|
||||
organizationRoles: organizationRoleEntityGuard.array(),
|
||||
});
|
||||
|
|
|
@ -60,7 +60,7 @@
|
|||
},
|
||||
"prettier": "@silverhand/eslint-config/.prettierrc",
|
||||
"dependencies": {
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"chalk": "^5.0.0",
|
||||
"find-up": "^7.0.0",
|
||||
"libphonenumber-js": "^1.9.49",
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@logto/language-kit": "workspace:^1.0.0",
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"@withtyped/client": "^0.7.22",
|
||||
"@withtyped/server": "^0.12.9"
|
||||
},
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
"devDependencies": {
|
||||
"@jest/types": "^29.0.3",
|
||||
"@silverhand/eslint-config": "5.0.0",
|
||||
"@silverhand/essentials": "^2.8.4",
|
||||
"@silverhand/essentials": "^2.8.8",
|
||||
"@silverhand/ts-config": "5.0.0",
|
||||
"@silverhand/ts-config-react": "5.0.0",
|
||||
"@types/color": "^3.0.3",
|
||||
|
|
202
pnpm-lock.yaml
202
pnpm-lock.yaml
|
@ -49,8 +49,8 @@ importers:
|
|||
specifier: ^3.0.2
|
||||
version: 3.0.2(tslib@2.4.1)(typescript@5.3.3)
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
applicationinsights:
|
||||
specifier: ^2.7.0
|
||||
version: 2.7.0
|
||||
|
@ -125,8 +125,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../shared
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
chalk:
|
||||
specifier: ^5.0.0
|
||||
version: 5.1.2
|
||||
|
@ -243,8 +243,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
dayjs:
|
||||
specifier: ^1.10.5
|
||||
version: 1.11.6
|
||||
|
@ -331,8 +331,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
dayjs:
|
||||
specifier: ^1.10.5
|
||||
version: 1.11.6
|
||||
|
@ -419,8 +419,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -498,8 +498,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -580,8 +580,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../shared
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -668,8 +668,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -750,8 +750,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -829,8 +829,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -908,8 +908,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -987,8 +987,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1066,8 +1066,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1148,8 +1148,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1227,8 +1227,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1306,8 +1306,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1388,8 +1388,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1467,8 +1467,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1546,8 +1546,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1625,8 +1625,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1704,8 +1704,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1783,8 +1783,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1862,8 +1862,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -1941,8 +1941,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2020,8 +2020,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2105,8 +2105,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../../shared
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2190,8 +2190,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
fast-xml-parser:
|
||||
specifier: ^4.2.5
|
||||
version: 4.2.5
|
||||
|
@ -2275,8 +2275,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2354,8 +2354,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2433,8 +2433,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2518,8 +2518,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2597,8 +2597,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2676,8 +2676,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2755,8 +2755,8 @@ importers:
|
|||
specifier: workspace:^2.0.0
|
||||
version: link:../../toolkit/connector-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.6
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
got:
|
||||
specifier: ^14.0.0
|
||||
version: 14.0.0
|
||||
|
@ -2894,8 +2894,8 @@ importers:
|
|||
specifier: 5.0.0
|
||||
version: 5.0.0(eslint@8.44.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.0.0)(typescript@5.3.3)
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
'@silverhand/ts-config':
|
||||
specifier: 5.0.0
|
||||
version: 5.0.0(typescript@5.3.3)
|
||||
|
@ -3182,8 +3182,8 @@ importers:
|
|||
specifier: workspace:^3.0.0
|
||||
version: link:../shared
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
'@simplewebauthn/server':
|
||||
specifier: ^8.2.0
|
||||
version: 8.2.0
|
||||
|
@ -3570,8 +3570,8 @@ importers:
|
|||
specifier: 5.0.0
|
||||
version: 5.0.0(eslint@8.44.0)(postcss@8.4.31)(prettier@3.0.0)(stylelint@15.0.0)(typescript@5.3.3)
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
'@silverhand/ts-config':
|
||||
specifier: 5.0.0
|
||||
version: 5.0.0(typescript@5.3.3)
|
||||
|
@ -3772,8 +3772,8 @@ importers:
|
|||
specifier: 5.0.0
|
||||
version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3)
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
'@silverhand/ts-config':
|
||||
specifier: 5.0.0
|
||||
version: 5.0.0(typescript@5.3.3)
|
||||
|
@ -3835,8 +3835,8 @@ importers:
|
|||
specifier: workspace:^1.0.0
|
||||
version: link:../toolkit/language-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
zod:
|
||||
specifier: ^3.22.4
|
||||
version: 3.22.4
|
||||
|
@ -3869,8 +3869,8 @@ importers:
|
|||
specifier: workspace:^1.0.0
|
||||
version: link:../toolkit/language-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
zod:
|
||||
specifier: ^3.22.4
|
||||
version: 3.22.4
|
||||
|
@ -3928,8 +3928,8 @@ importers:
|
|||
specifier: 5.0.0
|
||||
version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3)
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
'@silverhand/ts-config':
|
||||
specifier: 5.0.0
|
||||
version: 5.0.0(typescript@5.3.3)
|
||||
|
@ -3982,8 +3982,8 @@ importers:
|
|||
packages/shared:
|
||||
dependencies:
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
chalk:
|
||||
specifier: ^5.0.0
|
||||
version: 5.1.2
|
||||
|
@ -4037,8 +4037,8 @@ importers:
|
|||
specifier: workspace:^1.0.0
|
||||
version: link:../language-kit
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
'@withtyped/client':
|
||||
specifier: ^0.7.22
|
||||
version: 0.7.22(zod@3.22.4)
|
||||
|
@ -4107,8 +4107,8 @@ importers:
|
|||
specifier: 5.0.0
|
||||
version: 5.0.0(eslint@8.44.0)(prettier@3.0.0)(typescript@5.3.3)
|
||||
'@silverhand/essentials':
|
||||
specifier: ^2.8.4
|
||||
version: 2.8.4
|
||||
specifier: ^2.8.8
|
||||
version: 2.8.8
|
||||
'@silverhand/ts-config':
|
||||
specifier: 5.0.0
|
||||
version: 5.0.0(typescript@5.3.3)
|
||||
|
@ -7569,7 +7569,7 @@ packages:
|
|||
resolution: {integrity: sha512-yDWSZMI2Qo/xoYU92tnwSP/gnSvq8+CLK5DqD/4brO42QJa7xjt7eA+HSyuMmSUrKffY2nP3riU81gs+nR8DkA==}
|
||||
engines: {node: ^18.12.0}
|
||||
dependencies:
|
||||
'@silverhand/essentials': 2.8.6
|
||||
'@silverhand/essentials': 2.8.8
|
||||
tiny-cookie: 2.4.1
|
||||
dev: false
|
||||
|
||||
|
@ -7577,7 +7577,7 @@ packages:
|
|||
resolution: {integrity: sha512-8kKh1EcAm19smnEMvw0M51d2EQXEEH77G1JEKh1iLifUScmxD+c7HcN/5mLekaBz36MUVNiA2gE7s9L2GOpWrg==}
|
||||
dependencies:
|
||||
'@logto/client': 2.3.0
|
||||
'@silverhand/essentials': 2.8.6
|
||||
'@silverhand/essentials': 2.8.8
|
||||
js-base64: 3.7.5
|
||||
dev: true
|
||||
|
||||
|
@ -7585,7 +7585,7 @@ packages:
|
|||
resolution: {integrity: sha512-VrzsF+QtnrVXnDFbsdYTeGatjThlTFwtjTT/jJMaFdyRg0lno8vHxsjuyG8ba4wVSu22tSmJAr7okpAwRyhtcg==}
|
||||
dependencies:
|
||||
'@logto/js': 3.0.1
|
||||
'@silverhand/essentials': 2.8.6
|
||||
'@silverhand/essentials': 2.8.8
|
||||
camelcase-keys: 7.0.2
|
||||
jose: 5.0.1
|
||||
dev: true
|
||||
|
@ -7594,7 +7594,7 @@ packages:
|
|||
resolution: {integrity: sha512-cDKxCBFeZcG0CiGIa6mBY1Zgu3+tuvhYxs/qN0nQcj7MLSQ0AXHK9m1GeSJQH+Nu/jspggLmg27Ks8gdCHQUcg==}
|
||||
engines: {node: ^20.9.0}
|
||||
dependencies:
|
||||
'@silverhand/essentials': 2.8.6
|
||||
'@silverhand/essentials': 2.8.8
|
||||
'@withtyped/server': 0.12.9(zod@3.22.4)
|
||||
transitivePeerDependencies:
|
||||
- zod
|
||||
|
@ -7603,7 +7603,7 @@ packages:
|
|||
/@logto/js@3.0.1:
|
||||
resolution: {integrity: sha512-vsU6mH5oiiW3k00pMyVA4V31K2Bd0rOT9qWch2l5e5o1yCQLJ3zUIOjGjChu3m2TRu1d920iiUpZU3Lzf6Pwdw==}
|
||||
dependencies:
|
||||
'@silverhand/essentials': 2.8.6
|
||||
'@silverhand/essentials': 2.8.8
|
||||
camelcase-keys: 7.0.2
|
||||
jose: 5.0.1
|
||||
dev: true
|
||||
|
@ -7612,7 +7612,7 @@ packages:
|
|||
resolution: {integrity: sha512-xzVCnlrev/bqLtXOAw9I35h7njU1bed1jt6fL/VZfY4RUUJVZ36LG7fq2b7GsGg5xGRLchJ//+/VP1ac3+27YA==}
|
||||
dependencies:
|
||||
'@logto/client': 2.3.0
|
||||
'@silverhand/essentials': 2.8.6
|
||||
'@silverhand/essentials': 2.8.8
|
||||
js-base64: 3.7.5
|
||||
node-fetch: 2.7.0
|
||||
transitivePeerDependencies:
|
||||
|
@ -7625,7 +7625,7 @@ packages:
|
|||
react: '>=16.8.0 || ^18.0.0'
|
||||
dependencies:
|
||||
'@logto/browser': 2.2.0
|
||||
'@silverhand/essentials': 2.8.6
|
||||
'@silverhand/essentials': 2.8.8
|
||||
react: 18.2.0
|
||||
dev: true
|
||||
|
||||
|
@ -9298,13 +9298,9 @@ packages:
|
|||
lodash: 4.17.21
|
||||
dev: true
|
||||
|
||||
/@silverhand/essentials@2.8.4:
|
||||
resolution: {integrity: sha512-VaI00QyD2trA7n7/wHNcGNGRXoSr8dUGs/hQCu4Rju4Edl3vso7CeCXdfGU2aNDuT2uMs75of6Ph8gqVJhWlYQ==}
|
||||
engines: {node: ^16.13.0 || ^18.12.0 || ^19.2.0, pnpm: ^8.0.0}
|
||||
|
||||
/@silverhand/essentials@2.8.6:
|
||||
resolution: {integrity: sha512-qNyc6CvZRngP66hTA8sbpXGsiu9j6Hu62jCy7LV3tJiytg/hmxJB5oM9k5tpaUa9kHwYJ2X9CManX7SYYNrzHg==}
|
||||
engines: {node: ^16.13.0 || ^18.12.0 || ^19.2.0, pnpm: ^8.0.0}
|
||||
/@silverhand/essentials@2.8.8:
|
||||
resolution: {integrity: sha512-JCiNjdF9IcsF/7Gd4ZMAL3ykdujKrIvEpKa2Iz6YqUaoCSJEeyLwspE5xAHo38a0oT55Qa2pC+wLjEEgWAD8zA==}
|
||||
engines: {node: ^18.12.0 || ^20.9.0, pnpm: ^8.0.0}
|
||||
|
||||
/@silverhand/ts-config-react@5.0.0(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-DQpaG49sY36FhpyFIRAmTA5bG9ASFUVXu+yi29bMdLls51r9nEoBuWxWv2Sh3GnSGxKLq4gmFf+U8Zy/qcnX1w==}
|
||||
|
@ -10466,7 +10462,7 @@ packages:
|
|||
peerDependencies:
|
||||
zod: ^3.19.1
|
||||
dependencies:
|
||||
'@silverhand/essentials': 2.8.4
|
||||
'@silverhand/essentials': 2.8.8
|
||||
'@withtyped/shared': 0.2.2
|
||||
zod: 3.22.4
|
||||
|
||||
|
|
Loading…
Reference in a new issue