diff --git a/hooks/useConfig.js b/hooks/useConfig.js
index 8adedcaf..678b6d1c 100644
--- a/hooks/useConfig.js
+++ b/hooks/useConfig.js
@@ -2,7 +2,7 @@ import { useEffect } from 'react';
import useStore, { setConfig } from 'store/app';
import useApi from 'hooks/useApi';
-let fetched = false;
+let loading = false;
export default function useConfig() {
const { config } = useStore();
@@ -10,12 +10,13 @@ export default function useConfig() {
async function loadConfig() {
const { data } = await get('/config');
+ loading = false;
setConfig(data);
}
useEffect(() => {
- if (!config && !fetched) {
- fetched = true;
+ if (!config && !loading) {
+ loading = true;
loadConfig();
}
}, []);
diff --git a/lib/auth.js b/lib/auth.js
index 93027544..25985168 100644
--- a/lib/auth.js
+++ b/lib/auth.js
@@ -1,22 +1,26 @@
import { parseSecureToken, parseToken } from 'next-basics';
import { getAccount, getWebsite } from 'queries';
+import debug from 'debug';
import { SHARE_TOKEN_HEADER, TYPE_ACCOUNT, TYPE_WEBSITE } from 'lib/constants';
import { secret } from 'lib/crypto';
-export function getAuthToken(req) {
+const log = debug('umami:auth');
+
+export function parseAuthToken(req) {
try {
const token = req.headers.authorization;
-
return parseSecureToken(token.split(' ')[1], secret());
- } catch {
+ } catch (e) {
+ log(e);
return null;
}
}
-export function getShareToken(req) {
+export function parseShareToken(req) {
try {
return parseToken(req.headers[SHARE_TOKEN_HEADER], secret());
- } catch {
+ } catch (e) {
+ log(e);
return null;
}
}
@@ -29,6 +33,7 @@ export function isValidToken(token, validation) {
return validation(token);
}
} catch (e) {
+ log(e);
return false;
}
diff --git a/lib/crypto.js b/lib/crypto.js
index 74470549..ceb8aa99 100644
--- a/lib/crypto.js
+++ b/lib/crypto.js
@@ -9,11 +9,11 @@ export function secret() {
export function salt() {
const ROTATING_SALT = hash(startOfMonth(new Date()).toUTCString());
- return hash([secret(), ROTATING_SALT]);
+ return hash(secret(), ROTATING_SALT);
}
export function uuid(...args) {
if (!args.length) return v4();
- return v5(hash([...args, salt()]), v5.DNS);
+ return v5(hash(...args, salt()), v5.DNS);
}
diff --git a/lib/middleware.js b/lib/middleware.js
index 8189ea66..d42823fa 100644
--- a/lib/middleware.js
+++ b/lib/middleware.js
@@ -1,7 +1,7 @@
import { createMiddleware, unauthorized, badRequest, serverError } from 'next-basics';
import cors from 'cors';
import { getSession } from './session';
-import { getAuthToken, getShareToken } from './auth';
+import { parseAuthToken, parseShareToken } from './auth';
export const useCors = createMiddleware(cors());
@@ -26,8 +26,8 @@ export const useSession = createMiddleware(async (req, res, next) => {
});
export const useAuth = createMiddleware(async (req, res, next) => {
- const token = await getAuthToken(req);
- const shareToken = await getShareToken(req);
+ const token = await parseAuthToken(req);
+ const shareToken = await parseShareToken(req);
if (!token && !shareToken) {
return unauthorized(res);
diff --git a/package.json b/package.json
index aad3b913..e27b1f61 100644
--- a/package.json
+++ b/package.json
@@ -84,7 +84,7 @@
"maxmind": "^4.3.6",
"moment-timezone": "^0.5.35",
"next": "^12.3.1",
- "next-basics": "^0.18.0",
+ "next-basics": "^0.20.0",
"node-fetch": "^3.2.8",
"npm-run-all": "^4.1.5",
"prop-types": "^15.7.2",
diff --git a/pages/_app.js b/pages/_app.js
index 0d942f9d..c3617a08 100644
--- a/pages/_app.js
+++ b/pages/_app.js
@@ -2,34 +2,27 @@ import Head from 'next/head';
import { useRouter } from 'next/router';
import { IntlProvider } from 'react-intl';
import useLocale from 'hooks/useLocale';
+import useConfig from 'hooks/useConfig';
import 'styles/variables.css';
import 'styles/bootstrap-grid.css';
import 'styles/index.css';
import '@fontsource/inter/400.css';
import '@fontsource/inter/600.css';
-const Intl = ({ children }) => {
- const { locale, messages } = useLocale();
-
- const Wrapper = ({ children }) => {children};
-
- return (
-
- {children}
-
- );
-};
-
export default function App({ Component, pageProps }) {
+ const { locale, messages } = useLocale();
const { basePath } = useRouter();
const { dir } = useLocale();
+ useConfig();
+
+ const Wrapper = ({ children }) => {children};
if (process.env.uiDisabled) {
return null;
}
return (
-
+
@@ -45,6 +38,6 @@ export default function App({ Component, pageProps }) {
-
+
);
}
diff --git a/pages/sso.js b/pages/sso.js
new file mode 100644
index 00000000..c2c337ab
--- /dev/null
+++ b/pages/sso.js
@@ -0,0 +1,38 @@
+import { useEffect } from 'react';
+import debug from 'debug';
+import { useRouter } from 'next/router';
+import { setItem } from 'next-basics';
+import { AUTH_TOKEN } from 'lib/constants';
+import useApi from 'hooks/useApi';
+import { setUser } from 'store/app';
+
+const log = debug('umami:sso');
+
+export default function SingleSignOnPage() {
+ const router = useRouter();
+ const { get } = useApi();
+ const { token, url } = router.query;
+
+ useEffect(() => {
+ async function verify() {
+ setItem(AUTH_TOKEN, token);
+
+ const { ok, data } = await get('/auth/verify');
+
+ if (ok) {
+ log(data);
+ setUser(data);
+
+ if (url) {
+ await router.push(url);
+ }
+ }
+ }
+
+ if (token) {
+ verify();
+ }
+ }, [token]);
+
+ return null;
+}
diff --git a/yarn.lock b/yarn.lock
index ef95aaec..5aa6d841 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5244,10 +5244,10 @@ natural-compare@^1.4.0:
resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz"
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
-next-basics@^0.18.0:
- version "0.18.0"
- resolved "https://registry.yarnpkg.com/next-basics/-/next-basics-0.18.0.tgz#7683ec67d562fb57a6f3fb346c989802157450d1"
- integrity sha512-KJZjAHahQ++YYaSPuJVAY0wH9QYXVq85ZUGW5mBMq+qDfL8ZVG4nTWc8GhuI8EYLLR+oZp/eInvoqYgiW/dbhg==
+next-basics@^0.20.0:
+ version "0.20.0"
+ resolved "https://registry.yarnpkg.com/next-basics/-/next-basics-0.20.0.tgz#f88791dcc538438b5044695e37d58b4fdccc6dd8"
+ integrity sha512-KPqVVSzkKUvu9shvZt5Bp7Xv1nZ2xJRRqwqQ+a6a5JjsdE10Q3p07VLrT2ykl+v/CvR4sz98c0n+MaWpgO3Ckw==
dependencies:
base-x "^4.0.0"
bcryptjs "^2.4.3"