Accounts and login.

This commit is contained in:
Mike Cao 2020-07-23 19:56:55 -07:00
parent f3f0ad15f2
commit 49a55b40b4
22 changed files with 347 additions and 172 deletions

View file

@ -1,10 +1,10 @@
import React from 'react';
import Layout from 'components/layout';
import Layout from 'components/Layout';
export default function Custom404() {
return (
<Layout title="404 - Page Not Found">
<h1>oops</h1>
<Layout>
<h1>oops! not found</h1>
</Layout>
);
}

36
pages/admin.js Normal file
View file

@ -0,0 +1,36 @@
import React from 'react';
import cookies from 'next-cookies';
import Layout from 'components/Layout';
import { verifySecureToken } from 'lib/crypto';
export default function Admin({ username }) {
return (
<Layout title="Admin">
<h2>
You've successfully logged in as <b>{username}</b>.
</h2>
</Layout>
);
}
export async function getServerSideProps(context) {
const token = cookies(context)['umami.auth'];
try {
const payload = await verifySecureToken(token);
return {
props: {
username: payload.username,
},
};
} catch {
const { res } = context;
res.statusCode = 303;
res.setHeader('Location', '/');
res.end();
}
return { props: {} };
}

View file

@ -1,8 +1,11 @@
import { serialize } from 'cookie';
import { checkPassword, createSecureToken } from 'lib/crypto';
import { getAccount } from 'lib/db';
import { allowPost } from 'lib/middleware';
export default async (req, res) => {
await allowPost(req, res);
const { username, password } = req.body;
const account = await getAccount(username);
@ -10,13 +13,16 @@ export default async (req, res) => {
if (account && (await checkPassword(password, account.password))) {
const { user_id, username, is_admin } = account;
const token = await createSecureToken({ user_id, username, is_admin });
const expires = new Date(Date.now() + 31536000000);
const cookie = serialize('umami.auth', token, { expires, httpOnly: true });
const cookie = serialize('umami.auth', token, {
path: '/',
httpOnly: true,
maxAge: 60 * 60 * 24 * 365,
});
res.setHeader('Set-Cookie', [cookie]);
res.status(200).send({ token });
} else {
res.status(401).send('');
res.status(401).end();
}
};

View file

@ -8,25 +8,24 @@ export default async (req, res) => {
const session = await checkSession(req);
const token = await createToken(session);
const { website_id, session_id } = session;
const { type, payload } = req.body;
let ok = 1;
let ok = false;
if (type === 'pageview') {
const { url, referrer } = payload;
await savePageView(website_id, session_id, url, referrer).catch(e => {
ok = 0;
throw e;
});
await savePageView(website_id, session_id, url, referrer);
ok = true;
} else if (type === 'event') {
const { url, event_type, event_value } = payload;
await saveEvent(website_id, session_id, url, event_type, event_value).catch(() => {
ok = 0;
throw e;
});
}
const token = await createToken(session);
await saveEvent(website_id, session_id, url, event_type, event_value);
ok = true;
}
res.status(200).json({ ok, session: token });
};

View file

@ -7,6 +7,6 @@ export default async (req, res) => {
const payload = await verifySecureToken(token);
res.status(200).send(payload);
} catch {
res.status(400).send('');
res.status(400).end();
}
};

View file

@ -1,23 +1,17 @@
import React from 'react';
import Layout from 'components/layout';
import Link from 'next/link';
import Layout from 'components/Layout';
import Login from 'components/Login';
export default function Home() {
return (
<Layout>
Hello.
<br />
<Link href="/?q=abc">
<a>abc</a>
</Link>
<br />
<Link href="/?q=123">
<a>123</a>
</Link>
<br />
<button id="primary-button" className="otherClass umami--click--primary-button" type="button">
Button
</button>
<Login />
<p>
<Link href="/test">
<a>Test page 🡒</a>
</Link>
</p>
</Layout>
);
}

46
pages/test.js Normal file
View file

@ -0,0 +1,46 @@
import Head from 'next/head';
import Link from 'next/link';
import Layout from 'components/Layout';
export default function Test({ websiteId }) {
return (
<>
<Head>
{typeof window !== 'undefined' && (
<script async defer data-website-id={websiteId} src="/umami.js" />
)}
</Head>
<Layout>
<p>
Here you can test if your umami installation works. Open the network tab in your browser's
developer console and watch for requests to the url <b>collect</b>. The links below should
trigger page views. Clicking on the button should trigger an event.
</p>
<h2>Page links</h2>
<Link href="?q=1">
<a>Page One</a>
</Link>
<br />
<Link href="?q=2">
<a>Page Two</a>
</Link>
<h2>Events</h2>
<button
id="primary-button"
className="otherClass umami--click--primary-button"
type="button"
>
Button
</button>
</Layout>
</>
);
}
export async function getStaticProps() {
return {
props: {
websiteId: process.env.TEST_WEBSITE_ID,
},
};
}