jwt in http cookie remove menu

pull/3415/head
Sander Hahn 6 years ago
parent 8f30793c58
commit ad6fe57e6d

@ -2,7 +2,7 @@ import polka from 'polka';
import devalue from 'devalue';
import send from '@polka/send';
import { get, post } from 'httpie';
import { parse, stringify } from 'querystring';
import { parse, stringify, unescape, escape } from 'querystring';
import { decode, sign, verify } from './token';
import { find, query } from '../utils/db';
@ -25,13 +25,28 @@ function onError(err, req, res) {
res.headersSent || send(res, code, { error });
}
function cookies(req) {
if (!req.headers.hasOwnProperty("cookie")) {
return {};
}
return req.headers.cookie.split("; ").map((cookie) => {
const index = cookie.indexOf("=");
return [cookie.substring(0, index), cookie.substring(index+1)];
}).reduce((agg, [key, value]) => {
agg[unescape(key)] = unescape(value);
return agg;
}, {});
}
/**
* Middleware to determine User validity
*/
export async function isUser(req, res) {
const abort = exit.bind(null, res, 401);
const auth = req.headers.authorization;
const jwt_token = cookies(req).jwt_token
const auth = req.headers.authorization || (jwt_token && `Bearer ${jwt_token}`);
if (!auth) return abort('Missing Authorization header');
const [scheme, token] = auth.split(' ');
@ -112,14 +127,16 @@ export function API() {
returning *
`, [id, name, login, avatar_url, access_token]);
const user_props = toUser(user);
send(res, 200, `
<script>
window.opener.postMessage({
user: ${devalue(toUser(user))}
user: ${devalue(user_props)}
}, window.location.origin);
</script>
`, {
'Content-Type': 'text/html; charset=utf-8'
'Content-Type': 'text/html; charset=utf-8',
'Set-Cookie': `jwt_token=${escape(user_props.token)}; path=/; MaxAge=${30 * 24 * 60 * 60}; HttpOnly`
});
} catch (err) {
console.error('GET /auth/callback', err);
@ -129,6 +146,12 @@ export function API() {
});
}
});
app.delete('/logout', async (req, res) => {
send(res, 204, ``, {
'Set-Cookie': `jwt_token=; MaxAge=0; HttpOnly`
});
});
} else {
// Print "Misconfigured" error
app.get('/auth/login', (req, res) => {

@ -1,8 +1,6 @@
<script>
import { user, logout } from '../../../../../user.js';
export let load;
let showMenu = false;
let name;
@ -15,7 +13,6 @@
{#if showMenu}
<div class="menu">
<button on:click={load}>Archive</button>
<button on:click={logout}>Log out</button>
</div>
{/if}
@ -75,8 +72,6 @@
z-index: 99;
text-align: left;
border-radius: 0.4rem;
display: flex;
flex-direction: column;
}
.menu button {
@ -84,7 +79,6 @@
font-family: var(--font);
font-size: 1.6rem;
/* opacity: 0.7; */
padding: 0.4rem 0;
}
.menu button:hover {

@ -142,58 +142,6 @@
saving = false;
}
async function load() {
const periodFormatter = new Intl.DateTimeFormat(undefined, {
year: "numeric",
month: "long",
});
function sections(gists) {
const grouped = gists.reduce((agg, gist) => {
const key = periodFormatter.format(new Date(gist.updated_at));
if (!agg.hasOwnProperty(key)) {
agg[key] = [];
}
agg[key].push(gist);
return agg;
}, {});
return Object.entries(grouped).map(([title, archive]) => {
return {
title,
archive,
};
});
}
try {
const r = await fetch(`../repl/archive.json`, {
method: 'GET',
headers: { Authorization },
});
if (r.status < 200 || r.status >= 300) {
const { error } = await r.json();
throw new Error(`Received an HTTP ${r.status} response: ${error}`);
}
const gists = await r.json();
for (const section of sections(gists)) {
console.log(section.title);
for (const repl of section.archive) {
console.log(" " + repl.name);
console.log(" " + location.origin + "/repl/" + repl.uid);
}
}
} catch (err) {
if (navigator.onLine) {
alert(err.message);
} else {
alert(`It looks like you're offline! Find the internet and try again`);
}
}
}
async function download() {
downloading = true;
@ -268,7 +216,7 @@ export default app;` });
</button>
{#if $user}
<UserMenu {load} />
<UserMenu />
{:else}
<button class="icon" on:click={login}>
<Icon name="log-in" />

@ -2,6 +2,10 @@ import send from '@polka/send';
import { query } from '../../utils/db';
import { isUser } from '../../backend/auth';
const {
BASEURL,
} = process.env;
export async function get(req, res) {
const user = await isUser(req, res);
if (!user) return; // response already sent
@ -16,5 +20,10 @@ export async function get(req, res) {
offset $2
`, [user.id, offset]);
send(res, 200, rows);
send(res, 200, rows.map((row) => {
return {
url: `${BASEURL}/repl/${row.uid}`,
...row,
}
}));
}

@ -30,4 +30,7 @@ if (process.browser) {
export function logout() {
user.set(null);
fetch('/logout', {
method: 'DELETE',
});
}

Loading…
Cancel
Save