diff --git a/.npmrc b/.npmrc
index ee4bf8f32..ad46c0d5b 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1,4 +1,5 @@
# Hoist for Parcel
public-hoist-pattern[]=@parcel/*
public-hoist-pattern[]=postcss
+public-hoist-pattern[]=process
public-hoist-pattern[]=*eslint*
diff --git a/package.json b/package.json
index 63334c911..e2c97e8f7 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
},
"alias": {
"html-parse-stringify": "html-parse-stringify/dist/html-parse-stringify.module.js",
- "react-hook-form": "react-hook-form/dist/index.esm.mjs"
+ "react-hook-form": "react-hook-form/dist/index.esm.mjs",
+ "superstruct": "superstruct/lib/index.es.js"
}
}
diff --git a/packages/console/package.json b/packages/console/package.json
index 240047b1c..45cc76d2a 100644
--- a/packages/console/package.json
+++ b/packages/console/package.json
@@ -17,6 +17,7 @@
},
"dependencies": {
"@logto/phrases": "^0.1.0",
+ "@logto/react": "^0.1.2",
"@logto/schemas": "^0.1.0",
"@monaco-editor/react": "^4.3.1",
"@silverhand/essentials": "^1.1.6",
@@ -55,6 +56,7 @@
"postcss": "^8.4.6",
"postcss-modules": "^4.3.0",
"prettier": "^2.3.2",
+ "process": "^0.11.10",
"stylelint": "^13.13.1",
"typescript": "^4.6.2"
},
diff --git a/packages/console/src/App.module.scss b/packages/console/src/App.module.scss
deleted file mode 100644
index 5b7c6a57f..000000000
--- a/packages/console/src/App.module.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-@use '@/scss/underscore' as _;
-
-.content {
- flex-grow: 1;
- display: flex;
- padding-right: _.unit(5);
- margin-bottom: _.unit(6);
- overflow: hidden;
-}
diff --git a/packages/console/src/App.tsx b/packages/console/src/App.tsx
index e5fa00f8a..2a7e8c1a6 100644
--- a/packages/console/src/App.tsx
+++ b/packages/console/src/App.tsx
@@ -1,21 +1,21 @@
+import { LogtoProvider } from '@logto/react';
import React, { useEffect } from 'react';
import { BrowserRouter, Navigate, Route, Routes, useLocation, useNavigate } from 'react-router-dom';
import { SWRConfig } from 'swr';
import './scss/normalized.scss';
-import * as styles from './App.module.scss';
import AppContent from './components/AppContent';
-import Content from './components/Content';
-import Sidebar, { getPath, sections } from './components/Sidebar';
+import { getPath, sections } from './components/AppContent/components/Sidebar';
import Toast from './components/Toast';
-import Topbar from './components/Topbar';
import initI18n from './i18n/init';
import ApiResourceDetails from './pages/ApiResourceDetails';
import ApiResources from './pages/ApiResources';
import ApplicationDetails from './pages/ApplicationDetails';
import Applications from './pages/Applications';
+import Callback from './pages/Callback';
import ConnectorDetails from './pages/ConnectorDetails';
import Connectors from './pages/Connectors';
+import GetStarted from './pages/GetStarted';
import Users from './pages/Users';
import { fetcher } from './swr';
@@ -34,39 +34,37 @@ const Main = () => {
}, [location.pathname, navigate]);
return (
-
-
-
-
-
-
-
-
-
- } />
-
- } />
- } />
- } />
-
+
+
+
+
+ } />
+ }>
+ } />
+
+ } />
+
+ } />
+ } />
+ } />
-
- } />
- } />
-
-
- } />
- } />
- } />
-
-
- } />
-
-
-
-
-
-
+
+
+ } />
+ } />
+
+
+ } />
+ } />
+ } />
+
+
+ } />
+
+
+
+
+
);
};
diff --git a/packages/console/src/components/Sidebar/components/Item/index.module.scss b/packages/console/src/components/AppContent/components/Sidebar/components/Item/index.module.scss
similarity index 100%
rename from packages/console/src/components/Sidebar/components/Item/index.module.scss
rename to packages/console/src/components/AppContent/components/Sidebar/components/Item/index.module.scss
diff --git a/packages/console/src/components/Sidebar/components/Item/index.tsx b/packages/console/src/components/AppContent/components/Sidebar/components/Item/index.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/components/Item/index.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/components/Item/index.tsx
diff --git a/packages/console/src/components/Sidebar/components/Section/index.module.scss b/packages/console/src/components/AppContent/components/Sidebar/components/Section/index.module.scss
similarity index 100%
rename from packages/console/src/components/Sidebar/components/Section/index.module.scss
rename to packages/console/src/components/AppContent/components/Sidebar/components/Section/index.module.scss
diff --git a/packages/console/src/components/Sidebar/components/Section/index.tsx b/packages/console/src/components/AppContent/components/Sidebar/components/Section/index.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/components/Section/index.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/components/Section/index.tsx
diff --git a/packages/console/src/components/Sidebar/consts.ts b/packages/console/src/components/AppContent/components/Sidebar/consts.ts
similarity index 100%
rename from packages/console/src/components/Sidebar/consts.ts
rename to packages/console/src/components/AppContent/components/Sidebar/consts.ts
diff --git a/packages/console/src/components/Sidebar/icons/BarGraph.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/BarGraph.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/BarGraph.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/BarGraph.tsx
diff --git a/packages/console/src/components/Sidebar/icons/Bolt.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/Bolt.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/Bolt.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/Bolt.tsx
diff --git a/packages/console/src/components/Sidebar/icons/Box.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/Box.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/Box.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/Box.tsx
diff --git a/packages/console/src/components/Sidebar/icons/Cloud.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/Cloud.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/Cloud.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/Cloud.tsx
diff --git a/packages/console/src/components/Sidebar/icons/Connection.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/Connection.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/Connection.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/Connection.tsx
diff --git a/packages/console/src/components/Sidebar/icons/Document.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/Document.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/Document.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/Document.tsx
diff --git a/packages/console/src/components/Sidebar/icons/Gear.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/Gear.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/Gear.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/Gear.tsx
diff --git a/packages/console/src/components/Sidebar/icons/Help.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/Help.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/Help.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/Help.tsx
diff --git a/packages/console/src/components/Sidebar/icons/List.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/List.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/List.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/List.tsx
diff --git a/packages/console/src/components/Sidebar/icons/UserProfile.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/UserProfile.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/UserProfile.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/UserProfile.tsx
diff --git a/packages/console/src/components/Sidebar/icons/Web.tsx b/packages/console/src/components/AppContent/components/Sidebar/icons/Web.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/icons/Web.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/icons/Web.tsx
diff --git a/packages/console/src/components/Sidebar/index.module.scss b/packages/console/src/components/AppContent/components/Sidebar/index.module.scss
similarity index 100%
rename from packages/console/src/components/Sidebar/index.module.scss
rename to packages/console/src/components/AppContent/components/Sidebar/index.module.scss
diff --git a/packages/console/src/components/Sidebar/index.tsx b/packages/console/src/components/AppContent/components/Sidebar/index.tsx
similarity index 100%
rename from packages/console/src/components/Sidebar/index.tsx
rename to packages/console/src/components/AppContent/components/Sidebar/index.tsx
diff --git a/packages/console/src/components/Sidebar/utils.ts b/packages/console/src/components/AppContent/components/Sidebar/utils.ts
similarity index 100%
rename from packages/console/src/components/Sidebar/utils.ts
rename to packages/console/src/components/AppContent/components/Sidebar/utils.ts
diff --git a/packages/console/src/components/Topbar/index.module.scss b/packages/console/src/components/AppContent/components/Topbar/index.module.scss
similarity index 100%
rename from packages/console/src/components/Topbar/index.module.scss
rename to packages/console/src/components/AppContent/components/Topbar/index.module.scss
diff --git a/packages/console/src/components/Topbar/index.tsx b/packages/console/src/components/AppContent/components/Topbar/index.tsx
similarity index 100%
rename from packages/console/src/components/Topbar/index.tsx
rename to packages/console/src/components/AppContent/components/Topbar/index.tsx
diff --git a/packages/console/src/components/AppContent/index.module.scss b/packages/console/src/components/AppContent/index.module.scss
index e75884fe1..a4b179cc6 100644
--- a/packages/console/src/components/AppContent/index.module.scss
+++ b/packages/console/src/components/AppContent/index.module.scss
@@ -1,4 +1,5 @@
@use '@/scss/colors' as colors;
+@use '@/scss/underscore' as _;
.app {
position: absolute;
@@ -7,6 +8,18 @@
flex-direction: column;
}
+.content {
+ flex-grow: 1;
+ display: flex;
+ padding-right: _.unit(5);
+ margin-bottom: _.unit(6);
+ overflow: hidden;
+
+ .main {
+ flex-grow: 1;
+ }
+}
+
.light {
@include colors.light-theme;
}
diff --git a/packages/console/src/components/AppContent/index.tsx b/packages/console/src/components/AppContent/index.tsx
index 5fe800617..6e48f0e93 100644
--- a/packages/console/src/components/AppContent/index.tsx
+++ b/packages/console/src/components/AppContent/index.tsx
@@ -1,15 +1,21 @@
-import React, { ReactNode, useEffect } from 'react';
+import { useLogto } from '@logto/react';
+import React, { useEffect } from 'react';
+import { Outlet, useHref } from 'react-router-dom';
+import Sidebar from './components/Sidebar';
+import Topbar from './components/Topbar';
import * as styles from './index.module.scss';
type Theme = 'light';
type Props = {
- children: ReactNode;
theme: Theme;
};
-const AppContent = ({ children, theme }: Props) => {
+const AppContent = ({ theme }: Props) => {
+ const { isAuthenticated, signIn } = useLogto();
+ const href = useHref('/callback');
+
useEffect(() => {
const classes = [styles.web, styles[theme]].filter((value): value is string => Boolean(value));
document.body.classList.add(...classes);
@@ -19,7 +25,27 @@ const AppContent = ({ children, theme }: Props) => {
};
}, [theme]);
- return
{children}
;
+ useEffect(() => {
+ if (!isAuthenticated) {
+ void signIn(new URL(href, window.location.origin).toString());
+ }
+ }, [href, isAuthenticated, signIn]);
+
+ if (!isAuthenticated) {
+ return <>loading>;
+ }
+
+ return (
+
+ );
};
export default AppContent;
diff --git a/packages/console/src/components/Content/index.module.scss b/packages/console/src/components/Content/index.module.scss
deleted file mode 100644
index a13e02528..000000000
--- a/packages/console/src/components/Content/index.module.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-.content {
- flex-grow: 1;
-}
diff --git a/packages/console/src/components/Content/index.tsx b/packages/console/src/components/Content/index.tsx
deleted file mode 100644
index e1f1742bd..000000000
--- a/packages/console/src/components/Content/index.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import React, { ReactNode } from 'react';
-
-import * as styles from './index.module.scss';
-
-type Props = {
- children: ReactNode;
-};
-
-const Content = ({ children }: Props) => {
- return {children}
;
-};
-
-export default Content;
diff --git a/packages/console/src/pages/Callback/index.tsx b/packages/console/src/pages/Callback/index.tsx
new file mode 100644
index 000000000..f6aa8fdb0
--- /dev/null
+++ b/packages/console/src/pages/Callback/index.tsx
@@ -0,0 +1,19 @@
+import { useLogto } from '@logto/react';
+import React, { useEffect } from 'react';
+import { useNavigate } from 'react-router-dom';
+
+const Callback = () => {
+ const { isAuthenticated, isLoading } = useLogto();
+ const navigate = useNavigate();
+
+ // TO-DO: Error handling
+ useEffect(() => {
+ if (isAuthenticated && !isLoading) {
+ navigate('/', { replace: true });
+ }
+ }, [isAuthenticated, isLoading, navigate]);
+
+ return Redirecting...
;
+};
+
+export default Callback;
diff --git a/packages/console/src/pages/GetStarted/index.tsx b/packages/console/src/pages/GetStarted/index.tsx
new file mode 100644
index 000000000..f667aeece
--- /dev/null
+++ b/packages/console/src/pages/GetStarted/index.tsx
@@ -0,0 +1,7 @@
+import React from 'react';
+
+const GetStarted = () => {
+ return GetStarted
;
+};
+
+export default GetStarted;
diff --git a/packages/core/src/oidc/init.ts b/packages/core/src/oidc/init.ts
index 5f87b1dce..b97c0c819 100644
--- a/packages/core/src/oidc/init.ts
+++ b/packages/core/src/oidc/init.ts
@@ -91,7 +91,7 @@ export default async function initOidc(app: Koa): Promise {
clientBasedCORS: (_, origin) => {
console.log('origin', origin);
- return origin.startsWith('http://localhost:3000');
+ return origin.startsWith('http://localhost:3001');
},
findAccount: async (ctx, sub) => {
await findUserById(sub);
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index e96a1024f..b6df382b6 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -21,6 +21,7 @@ importers:
packages/console:
specifiers:
'@logto/phrases': ^0.1.0
+ '@logto/react': ^0.1.2
'@logto/schemas': ^0.1.0
'@monaco-editor/react': ^4.3.1
'@parcel/core': ^2.3.2
@@ -47,6 +48,7 @@ importers:
postcss: ^8.4.6
postcss-modules: ^4.3.0
prettier: ^2.3.2
+ process: ^0.11.10
react: ^17.0.2
react-dom: ^17.0.2
react-hook-form: ^7.27.1
@@ -61,6 +63,7 @@ importers:
typescript: ^4.6.2
dependencies:
'@logto/phrases': link:../phrases
+ '@logto/react': 0.1.2_react@17.0.2
'@logto/schemas': link:../schemas
'@monaco-editor/react': 4.3.1_e62f1489d5efe674a41c3f8d6971effe
'@silverhand/essentials': 1.1.6
@@ -98,6 +101,7 @@ importers:
postcss: 8.4.6
postcss-modules: 4.3.0_postcss@8.4.6
prettier: 2.5.1
+ process: 0.11.10
stylelint: 13.13.1
typescript: 4.6.2
@@ -2233,6 +2237,38 @@ packages:
prop-types: 15.8.1
react: 17.0.2
react-dom: 17.0.2_react@17.0.2
+ /@logto/browser/0.1.2:
+ resolution: {integrity: sha512-sTJjnx00BXYEChCbbO/LPs0x0wE1bDSHniFi+u93cynyEHgoT5yjMnH4N39NhrpmRdkXxOxaIkXmyAT1nSmYzQ==}
+ requiresBuild: true
+ dependencies:
+ '@logto/js': 0.1.2
+ '@silverhand/essentials': 1.1.6
+ jose: 4.6.0
+ lodash.get: 4.4.2
+ superstruct: 0.15.4
+ dev: false
+
+ /@logto/js/0.1.2:
+ resolution: {integrity: sha512-kz7l++gfpXa1OaUaB5WvnHNXQKEJDFnBzVYAofPADnPftHEF0zYRuQDCa8PJMd6/ECKfL1XPLMlJMNP/5U2fqQ==}
+ requiresBuild: true
+ dependencies:
+ '@silverhand/essentials': 1.1.6
+ camelcase-keys: 7.0.2
+ jose: 4.6.0
+ js-base64: 3.7.2
+ lodash.get: 4.4.2
+ superstruct: 0.15.4
+ dev: false
+
+ /@logto/react/0.1.2_react@17.0.2:
+ resolution: {integrity: sha512-kxLOvxOv3IB8BjpbcoRFsBFX249wAfbOL0tfJlSWmOXrkPouai1bRItEFBHFKDI1zLJATVQRoJNQfaczJy/c0A==}
+ requiresBuild: true
+ peerDependencies:
+ react: '>=16.8.0'
+ dependencies:
+ '@logto/browser': 0.1.2
+ '@silverhand/essentials': 1.1.6
+ react: 17.0.2
dev: false
/@nodelib/fs.scandir/2.1.5:
@@ -4506,6 +4542,16 @@ packages:
quick-lru: 4.0.1
dev: true
+ /camelcase-keys/7.0.2:
+ resolution: {integrity: sha512-Rjs1H+A9R+Ig+4E/9oyB66UC5Mj9Xq3N//vcLf2WzgdTi/3gUu3Z9KoqmlrEG4VuuLK8wJHofxzdQXz/knhiYg==}
+ engines: {node: '>=12'}
+ dependencies:
+ camelcase: 6.3.0
+ map-obj: 4.3.0
+ quick-lru: 5.1.1
+ type-fest: 1.4.0
+ dev: false
+
/camelcase/5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
@@ -4515,6 +4561,11 @@ packages:
resolution: {integrity: sha512-tVI4q5jjFV5CavAU8DXfza/TJcZutVKo/5Foskmsqcm0MsL91moHvwiGNnqaa2o6PF/7yT5ikDRcVcl8Rj6LCA==}
engines: {node: '>=10'}
+ /camelcase/6.3.0:
+ resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
+ engines: {node: '>=10'}
+ dev: false
+
/caniuse-api/3.0.0:
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
dependencies:
@@ -8568,6 +8619,14 @@ packages:
resolution: {integrity: sha512-S7Xfsy8nN9Iw/AZxk+ZxEbd5ImIwJPM0TfAo8zI8FF+3lidQ2yiK4dqzsaPKSbZD0woNVSY0KCql6rlKc5V7ug==}
dev: false
+ /jose/4.6.0:
+ resolution: {integrity: sha512-0hNAkhMBNi4soKSAX4zYOFV+aqJlEz/4j4fregvasJzEVtjDChvWqRjPvHwLqr5hx28Ayr6bsOs1Kuj87V0O8w==}
+ dev: false
+
+ /js-base64/3.7.2:
+ resolution: {integrity: sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==}
+ dev: false
+
/js-tokens/4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -9073,7 +9132,6 @@ packages:
/lodash.get/4.4.2:
resolution: {integrity: sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=}
- dev: true
/lodash.ismatch/4.4.0:
resolution: {integrity: sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=}
@@ -11565,6 +11623,11 @@ packages:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
dev: true
+ /process/0.11.10:
+ resolution: {integrity: sha1-czIwDoQBYb2j5podHZGn1LwW8YI=}
+ engines: {node: '>= 0.6.0'}
+ dev: true
+
/promise-deferred/2.0.3:
resolution: {integrity: sha512-n10XaoznCzLfyPFOlEE8iurezHpxrYzyjgq/1eW9Wk1gJwur/N7BdBmjJYJpqMeMcXK4wEbzo2EvZQcqjYcKUQ==}
engines: {node: '>= 0.4'}
@@ -13156,6 +13219,10 @@ packages:
- supports-color
dev: true
+ /superstruct/0.15.4:
+ resolution: {integrity: sha512-eOoMeSbP9ZJChNOm/9RYjE+F36rYR966AAqeG3xhQB02j2sfAUXDp4EQ/7bAOqnlJnuFDB8yvOu50SocvKpUEw==}
+ dev: false
+
/supertest/6.2.2:
resolution: {integrity: sha512-wCw9WhAtKJsBvh07RaS+/By91NNE0Wh0DN19/hWPlBOU8tAfOtbZoVSV4xXeoKoxgPx0rx2y+y+8660XtE7jzg==}
engines: {node: '>=6.0.0'}
@@ -13666,6 +13733,11 @@ packages:
engines: {node: '>=8'}
dev: true
+ /type-fest/1.4.0:
+ resolution: {integrity: sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==}
+ engines: {node: '>=10'}
+ dev: false
+
/type-fest/2.8.0:
resolution: {integrity: sha512-O+V9pAshf9C6loGaH0idwsmugI2LxVNR7DtS40gVo2EXZVYFgz9OuNtOhgHLdHdapOEWNdvz9Ob/eeuaWwwlxA==}
engines: {node: '>=12.20'}