Refactor auth logic.

This commit is contained in:
Mike Cao 2022-10-11 21:48:33 -07:00
parent edd1751b81
commit 5e2d23f18f
10 changed files with 40 additions and 30 deletions

View File

@ -17,8 +17,8 @@ export default function WebsiteHeader({ websiteId, title, domain, showLink = fal
<Favicon domain={domain} />
<Link
className={styles.titleLink}
href="/website/[...id]"
as={`/website/${websiteId}/${title}`}
href="/websites/[...id]"
as={`/websites/${websiteId}/${title}`}
>
<OverflowText tooltipId={`${websiteId}-title`}>{title}</OverflowText>
</Link>
@ -41,8 +41,8 @@ export default function WebsiteHeader({ websiteId, title, domain, showLink = fal
<RefreshButton websiteId={websiteId} />
{showLink && (
<Link
href="/website/[...id]"
as={`/website/${websiteId}/${title}`}
href="/websites/[...id]"
as={`/websites/${websiteId}/${title}`}
className={styles.link}
icon={<Arrow />}
size="small"

View File

@ -55,7 +55,7 @@ export default function TestConsole() {
<PageHeader>
<div>Test Console</div>
<DropDown
value={selectedValue || 'Select websites'}
value={selectedValue || 'Select website'}
options={options}
onChange={handleSelect}
/>

View File

@ -84,7 +84,7 @@ export default function WebsiteSettings() {
);
const DetailsLink = ({ id, name, domain }) => (
<Link className={styles.detailLink} href="/website/[...id]" as={`/website/${id}/${name}`}>
<Link className={styles.detailLink} href="/websites/[...id]" as={`/websites/${id}/${name}`}>
<Favicon domain={domain} />
<OverflowText tooltipId={`${id}-name`}>{name}</OverflowText>
</Link>

View File

@ -1,10 +1,10 @@
import { validate } from 'uuid';
import { parseSecureToken, parseToken, getItem } from 'next-basics';
import { AUTH_TOKEN, SHARE_TOKEN_HEADER } from './constants';
import { parseSecureToken, parseToken } from 'next-basics';
import { getWebsite } from 'queries';
import { secret } from './crypto';
import { SHARE_TOKEN_HEADER } from 'lib/constants';
import { secret } from 'lib/crypto';
export async function getAuthToken(req) {
export function getAuthToken(req) {
try {
const token = req.headers.authorization;
@ -14,13 +14,15 @@ export async function getAuthToken(req) {
}
}
export function getAuthHeader() {
const token = getItem(AUTH_TOKEN);
return token ? { authorization: `Bearer ${token}` } : {};
export function getShareToken(req) {
try {
return parseSecureToken(req.headers[SHARE_TOKEN_HEADER], secret());
} catch {
return null;
}
}
export async function isValidToken(token, validation) {
export function isValidToken(token, validation) {
try {
const result = parseToken(token, secret());

View File

@ -1,7 +1,7 @@
import { createMiddleware, unauthorized, badRequest, serverError } from 'next-basics';
import cors from 'cors';
import { getSession } from './session';
import { getAuthToken } from './auth';
import { getAuthToken, getShareToken } from './auth';
export const useCors = createMiddleware(cors());
@ -27,11 +27,12 @@ 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);
if (!token) {
return unauthorized(res);
}
req.auth = token;
req.auth = { ...token, shareToken };
next();
});

View File

@ -31,7 +31,7 @@ export async function getSession(req) {
let websiteId = null;
// Check if websites exists
// Check if website exists
if (redis.enabled) {
websiteId = Number(await redis.get(`website:${websiteUuid}`));
}

View File

@ -84,7 +84,7 @@
"maxmind": "^4.3.6",
"moment-timezone": "^0.5.35",
"next": "^12.2.5",
"next-basics": "^0.12.0",
"next-basics": "^0.17.0",
"node-fetch": "^3.2.8",
"npm-run-all": "^4.1.5",
"prop-types": "^15.7.2",

View File

@ -9,10 +9,10 @@ export default async (req, res) => {
const website = await getWebsiteByShareId(id);
if (website) {
const websiteId = website.websiteId;
const token = createToken({ websiteId: websiteId }, secret());
const { websiteId, websiteUuid } = website;
const token = createToken({ websiteId, websiteUuid }, secret());
return ok(res, { websiteId, token });
return ok(res, { websiteId, websiteUuid, token });
}
return notFound(res);

View File

@ -5,6 +5,10 @@ import { useAuth, useCors } from 'lib/middleware';
import { validate } from 'uuid';
export default async (req, res) => {
await useAuth(req, res);
const { isAdmin, userId, accountUuid } = req.auth;
const { id } = req.query;
const websiteId = +id;
@ -23,9 +27,6 @@ export default async (req, res) => {
}
if (req.method === 'POST') {
await useAuth(req, res);
const { isAdmin: currentUserIsAdmin, userId: currentUserId, accountUuid } = req.auth;
const { name, domain, owner, enable_share_url } = req.body;
let account;
@ -37,7 +38,7 @@ export default async (req, res) => {
const shareId = enable_share_url ? website.shareId || getRandomChars(8) : null;
if (website.userId !== currentUserId && !currentUserIsAdmin) {
if (website.userId !== userId && !isAdmin) {
return unauthorized(res);
}

View File

@ -2273,6 +2273,11 @@ balanced-match@^2.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-2.0.0.tgz#dc70f920d78db8b858535795867bf48f820633d9"
integrity sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==
base-x@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a"
integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e"
@ -4731,11 +4736,12 @@ 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.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/next-basics/-/next-basics-0.12.0.tgz#e946cdb3f32d5d84f67e7c35b6e2e96750763c62"
integrity sha512-3meED1Z9m8QvOsG4bz5OAuyjROdV9Cf75Wq2t+cHiGBh+y8qhTluJduqIXuoY5x0S72/5XvY1mwthW+Og47H9A==
next-basics@^0.17.0:
version "0.17.0"
resolved "https://registry.yarnpkg.com/next-basics/-/next-basics-0.17.0.tgz#567c7b7a05f02bf6e4a073090954c1b6de4e7045"
integrity sha512-NXYfbdBCdbn/a6x4F+7zZGmJ8llHtZcUYp3BMwoYXRSPsa1Y4wmJgIgtGBu542IMfTkQ2YClBy3Z1gOoMbzgaQ==
dependencies:
base-x "^4.0.0"
bcryptjs "^2.4.3"
jsonwebtoken "^8.5.1"