0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

chore: upgrade logto sdks (#5011)

* chore: upgrade logto sdks

* chore: fix tests

* fix(demo-app): fix hook infinite loop issue

* refactor(demo-app): use enum from sdk
This commit is contained in:
Gao Sun 2023-12-02 15:22:27 +08:00 committed by GitHub
parent e1a162eb56
commit fc9c9ea721
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 65 additions and 107 deletions

View file

@ -32,7 +32,7 @@
"@logto/language-kit": "workspace:^1.0.0",
"@logto/phrases": "workspace:^1.7.0",
"@logto/phrases-experience": "workspace:^1.4.0",
"@logto/react": "^2.1.2",
"@logto/react": "^2.2.0",
"@logto/schemas": "workspace:^1.11.0",
"@logto/shared": "workspace:^3.0.0",
"@mdx-js/react": "^1.6.22",

View file

@ -22,7 +22,7 @@
"@logto/core-kit": "workspace:^2.0.0",
"@logto/language-kit": "workspace:^1.0.0",
"@logto/phrases": "workspace:^1.2.0",
"@logto/react": "^2.1.0",
"@logto/react": "^2.2.0",
"@logto/schemas": "workspace:^1.2.3",
"@parcel/core": "2.9.3",
"@parcel/transformer-sass": "2.9.3",

View file

@ -1,5 +1,5 @@
import type { IdTokenClaims } from '@logto/react';
import { LogtoProvider, useLogto, Prompt } from '@logto/react';
import { LogtoProvider, useLogto, Prompt, UserScope } from '@logto/react';
import { demoAppApplicationId } from '@logto/schemas';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
@ -22,19 +22,25 @@ const Main = () => {
const [congratsIcon, setCongratsIcon] = useState<string>(isDarkMode ? congratsDark : congrats);
useEffect(() => {
if (isInCallback) {
if (isInCallback || isLoading) {
return;
}
if (isAuthenticated) {
(async () => {
const userInfo = await getIdTokenClaims();
setUser(userInfo ?? { sub: 'N/A', username: 'N/A' });
})();
} else if (!isLoading) {
const loadIdTokenClaims = async () => {
const userInfo = await getIdTokenClaims();
setUser(userInfo ?? { sub: 'N/A', username: 'N/A' });
};
// If user is authenticated but user info is not loaded yet, load it
if (isAuthenticated && !user) {
void loadIdTokenClaims();
}
// If user is not authenticated, redirect to sign-in page
if (!isAuthenticated) {
void signIn(window.location.href);
}
}, [getIdTokenClaims, isAuthenticated, isLoading, isInCallback, signIn, t]);
}, [getIdTokenClaims, isAuthenticated, isInCallback, isLoading, signIn, user]);
useEffect(() => {
const onThemeChange = (event: MediaQueryListEvent) => {
@ -102,9 +108,7 @@ const App = () => {
endpoint: window.location.origin,
appId: demoAppApplicationId,
prompt: Prompt.Login,
// TODO: Use enum values once JS SDK is updated
scopes: ['urn:logto:scope:organizations', 'urn:logto:scope:organization_roles'],
resources: ['urn:logto:resource:organizations'],
scopes: [UserScope.Organizations, UserScope.OrganizationRoles],
}}
>
<Main />

View file

@ -25,8 +25,8 @@
"@jest/test-sequencer": "^29.5.0",
"@jest/types": "^29.1.2",
"@logto/connector-kit": "workspace:^2.0.0",
"@logto/js": "^2.1.1",
"@logto/node": "^2.1.1",
"@logto/js": "^3.0.1",
"@logto/node": "^2.2.0",
"@logto/schemas": "workspace:^1.10.1",
"@logto/shared": "workspace:^3.0.0",
"@silverhand/eslint-config": "4.0.1",

View file

@ -1,23 +1,23 @@
import type { Storage, StorageKey } from '@logto/node';
import type { PersistKey, Storage } from '@logto/node';
import type { Nullable } from '@silverhand/essentials';
export class MemoryStorage implements Storage {
private storage: { [key in StorageKey]: Nullable<string> } = {
export class MemoryStorage implements Storage<PersistKey> {
private storage: { [key in PersistKey]: Nullable<string> } = {
idToken: null,
refreshToken: null,
accessToken: null,
signInSession: null,
};
async getItem(key: StorageKey): Promise<Nullable<string>> {
async getItem(key: PersistKey): Promise<Nullable<string>> {
return this.storage[key];
}
async setItem(key: StorageKey, value: string): Promise<void> {
async setItem(key: PersistKey, value: string): Promise<void> {
this.storage[key] = value;
}
async removeItem(key: StorageKey): Promise<void> {
async removeItem(key: PersistKey): Promise<void> {
this.storage[key] = null;
}
}

View file

@ -77,20 +77,16 @@ describe('OpenID Connect ID token', () => {
await organizationApi.addUserRoles(org1.id, userId, [role.id]);
// Organizations claim
const idToken = await fetchIdToken(['urn:logto:scope:organizations']);
// @ts-expect-error type definition needs to be updated
const organizations = idToken.organizations as unknown;
const { organizations } = await fetchIdToken(['urn:logto:scope:organizations']);
expect(organizations).toHaveLength(2);
expect(organizations).toContainEqual(org1.id);
expect(organizations).toContainEqual(org2.id);
// Organization roles claim
const idToken2 = await fetchIdToken(['urn:logto:scope:organization_roles']);
// @ts-expect-error type definition needs to be updated
const organizationRoles = idToken2.organization_roles as unknown;
const { organization_roles: organizationRoles } = await fetchIdToken([
'urn:logto:scope:organization_roles',
]);
expect(organizationRoles).toHaveLength(1);
expect(organizationRoles).toContainEqual(`${org1.id}:${role.name}`);

View file

@ -1,7 +1,7 @@
import assert from 'node:assert';
import { decodeAccessToken } from '@logto/js';
import { type LogtoConfig, Prompt } from '@logto/node';
import { type LogtoConfig, Prompt, PersistKey } from '@logto/node';
import { GrantType, InteractionEvent, demoAppApplicationId } from '@logto/schemas';
import { isKeyInObject, removeUndefinedKeys } from '@silverhand/essentials';
import { HTTPError, got } from 'got';
@ -61,7 +61,7 @@ class MockOrganizationClient extends MockClient {
})
.json();
if (isKeyInObject(json, 'refresh_token')) {
await this.storage.setItem('refreshToken', String(json.refresh_token));
await this.storage.setItem(PersistKey.RefreshToken, String(json.refresh_token));
}
return json;
} catch (error) {
@ -267,7 +267,7 @@ describe('`refresh_token` grant (for organization tokens)', () => {
await expect(client.fetchOrganizationToken(org.id)).rejects.toMatchError(accessDeniedError);
});
it('should not issue organization scopes when organization resource is not requested', async () => {
it('should issue organization scopes even organization resource is not requested (handled by SDK)', async () => {
const { orgs } = await initOrganizations();
const client = await initClient({
@ -276,11 +276,11 @@ describe('`refresh_token` grant (for organization tokens)', () => {
});
expectGrantResponse(await client.fetchOrganizationToken(orgs[0].id), {
organizationId: orgs[0].id,
scopes: [],
scopes: ['scope1', 'scope2'],
});
expectGrantResponse(await client.fetchOrganizationToken(orgs[1].id), {
organizationId: orgs[1].id,
scopes: [],
scopes: ['scope1', 'scope2'],
});
expectGrantResponse(await client.fetchOrganizationToken(orgs[2].id), {
organizationId: orgs[2].id,

View file

@ -2858,8 +2858,8 @@ importers:
specifier: workspace:^1.4.0
version: link:../phrases-experience
'@logto/react':
specifier: ^2.1.2
version: 2.1.2(react@18.2.0)
specifier: ^2.2.0
version: 2.2.0(react@18.2.0)
'@logto/schemas':
specifier: workspace:^1.11.0
version: link:../schemas
@ -3435,8 +3435,8 @@ importers:
specifier: workspace:^1.2.0
version: link:../phrases
'@logto/react':
specifier: ^2.1.0
version: 2.1.0(react@18.2.0)
specifier: ^2.2.0
version: 2.2.0(react@18.2.0)
'@logto/schemas':
specifier: workspace:^1.2.3
version: link:../schemas
@ -3745,11 +3745,11 @@ importers:
specifier: workspace:^2.0.0
version: link:../toolkit/connector-kit
'@logto/js':
specifier: ^2.1.1
version: 2.1.1
specifier: ^3.0.1
version: 3.0.1
'@logto/node':
specifier: ^2.1.1
version: 2.1.1
specifier: ^2.2.0
version: 2.2.0
'@logto/schemas':
specifier: workspace:^1.10.1
version: link:../schemas
@ -7479,47 +7479,21 @@ packages:
tiny-cookie: 2.4.1
dev: false
/@logto/browser@2.1.0:
resolution: {integrity: sha512-4XsXlCC0uZHcfazV09/4YKo4koqvSzQlkPUAToTp/WHpb6h2XDOJh5/hi55LXL4zp0PCcgpErKRxFCtgXCc6WQ==}
/@logto/browser@2.2.0:
resolution: {integrity: sha512-8kKh1EcAm19smnEMvw0M51d2EQXEEH77G1JEKh1iLifUScmxD+c7HcN/5mLekaBz36MUVNiA2gE7s9L2GOpWrg==}
dependencies:
'@logto/client': 2.2.0
'@silverhand/essentials': 2.8.4
'@logto/client': 2.3.0
'@silverhand/essentials': 2.8.5
js-base64: 3.7.5
dev: true
/@logto/browser@2.1.2:
resolution: {integrity: sha512-LADZHT7LTyiWDwWmBwh3qAtOg+IVEjfaFKBTB/RQBc5T9xYO4q4JcyW1XgpMlkc0uLqOtW3uOGztUVs0ugi6/g==}
/@logto/client@2.3.0:
resolution: {integrity: sha512-VrzsF+QtnrVXnDFbsdYTeGatjThlTFwtjTT/jJMaFdyRg0lno8vHxsjuyG8ba4wVSu22tSmJAr7okpAwRyhtcg==}
dependencies:
'@logto/client': 2.2.3
'@silverhand/essentials': 2.8.4
js-base64: 3.7.5
dev: true
/@logto/client@2.1.0:
resolution: {integrity: sha512-vw8xDW8k38/58Q1r592z/9JdsmUh4+LMmoVm/Nu7LbWKlT32eD3H9hZDkFK9XEHpriifhI0hP7asGWEmhrEUuQ==}
dependencies:
'@logto/js': 2.1.1
'@silverhand/essentials': 2.8.4
camelcase-keys: 7.0.2
jose: 4.14.4
dev: true
/@logto/client@2.2.0:
resolution: {integrity: sha512-7I2ELo5UWIJsFCYK/gX465l0+QhXTdyYWkgb2CcdPu5KbaPBNpASedm+fEV2NREYe2svbNODFhog6UMA/xGQnQ==}
dependencies:
'@logto/js': 2.1.1
'@logto/js': 3.0.1
'@silverhand/essentials': 2.8.5
camelcase-keys: 7.0.2
jose: 4.14.4
dev: true
/@logto/client@2.2.3:
resolution: {integrity: sha512-xq4LhQ6ItbukAHgsMDcgfspTpdpO5sSfSEugpOrGP/nLwzGTfBO78OSUfMdBQEDr5+3SRmONuSjUBBwssOLINA==}
dependencies:
'@logto/js': 2.1.3
'@silverhand/essentials': 2.8.5
camelcase-keys: 7.0.2
jose: 4.14.4
jose: 5.0.1
dev: true
/@logto/cloud@0.2.5-5a698db(zod@3.22.4):
@ -7532,50 +7506,32 @@ packages:
- zod
dev: true
/@logto/js@2.1.1:
resolution: {integrity: sha512-PHikheavVK+l4ivgtzi14p184hEPgXjqQEAom1Gme1MZoopx+WlwxvHSEQBsmyvVqRtI0oiojhoU5tgYi1FKJw==}
dependencies:
'@silverhand/essentials': 2.8.4
camelcase-keys: 7.0.2
jose: 4.14.4
dev: true
/@logto/js@2.1.3:
resolution: {integrity: sha512-TOuoC5gHx/SfY5gcGSBfw63x5TpM6Lm/9J5y0Jy003Z1DZARUlpz0KbzyCVAIC/+6qIefkmNPHKl1rq9MB/hog==}
/@logto/js@3.0.1:
resolution: {integrity: sha512-vsU6mH5oiiW3k00pMyVA4V31K2Bd0rOT9qWch2l5e5o1yCQLJ3zUIOjGjChu3m2TRu1d920iiUpZU3Lzf6Pwdw==}
dependencies:
'@silverhand/essentials': 2.8.5
camelcase-keys: 7.0.2
jose: 4.14.4
jose: 5.0.1
dev: true
/@logto/node@2.1.1:
resolution: {integrity: sha512-joSzzAqaRKeEquRenoFrIXXkNxkJci5zSkk4afywz1P8tTcTysnV4eXaBmwXNpmDfQdtHBwRdSACZPLgeF8JiQ==}
/@logto/node@2.2.0:
resolution: {integrity: sha512-xzVCnlrev/bqLtXOAw9I35h7njU1bed1jt6fL/VZfY4RUUJVZ36LG7fq2b7GsGg5xGRLchJ//+/VP1ac3+27YA==}
dependencies:
'@logto/client': 2.1.0
'@silverhand/essentials': 2.8.4
'@logto/client': 2.3.0
'@silverhand/essentials': 2.8.5
js-base64: 3.7.5
node-fetch: 2.6.7
node-fetch: 2.7.0
transitivePeerDependencies:
- encoding
dev: true
/@logto/react@2.1.0(react@18.2.0):
resolution: {integrity: sha512-xP/EW/N7Fh/5yyogCavCf43U114hiuACGxWql8CTmCbSJEXKVU5kiHNQXi2upV7AvB+lNA1as7LT/KbR9wM/2Q==}
/@logto/react@2.2.0(react@18.2.0):
resolution: {integrity: sha512-XSIptaw5o1mmflhG0eYD49aNBONfOIIjoyyam12qQOOfL2EFMZghIfaheh2SzemIT3LAawX2+yqAB/lo1rIGWA==}
peerDependencies:
react: '>=16.8.0 || ^18.0.0'
dependencies:
'@logto/browser': 2.1.0
'@silverhand/essentials': 2.8.4
react: 18.2.0
dev: true
/@logto/react@2.1.2(react@18.2.0):
resolution: {integrity: sha512-4Fz5GG5N7y9ynYVutuLZgBornkVccaxG1vmAOxt233wfFPmNzESJ+TlYGe2FbngC7z9xfT6c7f9Q+1LZQmrzVg==}
peerDependencies:
react: '>=16.8.0 || ^18.0.0'
dependencies:
'@logto/browser': 2.1.2
'@silverhand/essentials': 2.8.4
'@logto/browser': 2.2.0
'@silverhand/essentials': 2.8.5
react: 18.2.0
dev: true
@ -15195,6 +15151,7 @@ packages:
/jose@4.14.4:
resolution: {integrity: sha512-j8GhLiKmUAh+dsFXlX1aJCbt5KMibuKb+d7j1JaOJG6s2UjX1PQlW+OKB/sD4a/5ZYF4RcmYmLSndOoU3Lt/3g==}
dev: false
/jose@5.0.1:
resolution: {integrity: sha512-gRVzy7s3RRdGbXmcTdlOswJOjhwPLx1ijIgAqLY6ktzFpOJxxYn4l0fC2vHaHHi4YBX/5FOL3aY+6W0cvQgpug==}
@ -16805,6 +16762,7 @@ packages:
optional: true
dependencies:
whatwg-url: 5.0.0
dev: false
/node-fetch@2.7.0:
resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==}