From f672e6a721fd0e083e15268acf7c0b6f73825856 Mon Sep 17 00:00:00 2001 From: Luke Edwards Date: Thu, 25 Apr 2019 22:10:32 -0700 Subject: [PATCH] feat: save new gists to database --- site/migrations/001-create-gists.js | 24 ++++++++ site/package.json | 1 - site/src/backend/auth.js | 3 +- site/src/routes/gist/create.js | 57 ++++++------------- .../repl/_components/AppControls/index.svelte | 4 +- 5 files changed, 43 insertions(+), 46 deletions(-) create mode 100644 site/migrations/001-create-gists.js diff --git a/site/migrations/001-create-gists.js b/site/migrations/001-create-gists.js new file mode 100644 index 0000000000..22293f5737 --- /dev/null +++ b/site/migrations/001-create-gists.js @@ -0,0 +1,24 @@ +exports.up = DB => { + DB.sql(` + create table if not exists gists ( + id serial primary key, + uid uuid NOT NULL DEFAULT gen_random_uuid(), + user_id integer REFERENCES users(id) not null, + name character varying(255) not null, + files json not null, + created_at timestamp with time zone NOT NULL DEFAULT now(), + updated_at timestamp with time zone + ); + + create unique index if not exists gists_pkey ON gists(id int4_ops); + create index if not exists gists_user_id_key ON gists(user_id int4_ops); + `); +}; + +exports.down = DB => { + DB.sql(` + drop table if exists gists cascade; + drop index if exists gists_user_id_key; + drop index if exists gists_pkey; + `); +}; diff --git a/site/package.json b/site/package.json index 7ca063c3bc..ad9177cdc4 100644 --- a/site/package.json +++ b/site/package.json @@ -15,7 +15,6 @@ "testsrc": "mocha -r esm test/**" }, "dependencies": { - "@polka/parse": "^1.0.0-next.1", "@polka/send": "^1.0.0-next.2", "devalue": "^1.1.0", "do-not-zip": "^1.0.0", diff --git a/site/src/backend/auth.js b/site/src/backend/auth.js index 5072f0c3cd..674f4a4c2c 100644 --- a/site/src/backend/auth.js +++ b/site/src/backend/auth.js @@ -2,7 +2,6 @@ import polka from 'polka'; import devalue from 'devalue'; import send from '@polka/send'; import { get, post } from 'httpie'; -import { json } from '@polka/parse'; import { parse, stringify } from 'querystring'; import { decode, sign, verify } from './token'; import { find, query } from '../utils/db'; @@ -65,7 +64,7 @@ export function toUser(obj={}) { } export function API() { - const app = polka({ onError }).use(json()); + const app = polka({ onError }); if (GITHUB_CLIENT_ID) { app.get('/auth/login', (req, res) => { diff --git a/site/src/routes/gist/create.js b/site/src/routes/gist/create.js index d67ea9b313..13c1b912ca 100644 --- a/site/src/routes/gist/create.js +++ b/site/src/routes/gist/create.js @@ -1,55 +1,30 @@ -import fetch from 'node-fetch'; -import { body } from './_utils.js'; import send from '@polka/send'; +import { query } from '../../utils/db'; +import { isUser } from '../../backend/auth'; +import { body } from './_utils.js'; export async function post(req, res) { - const user = req.session.passport && req.session.passport.user; - - if (!user) { - return send(res, 403, { error: 'unauthorized' }); - } + const user = await isUser(req, res); + if (!user) return; // response already sent try { const { name, components } = await body(req); - const files = { - 'meta.json': { - content: JSON.stringify({ - svelte: true - }, null, ' ') - }, - 'README.md': { - content: `Created with [svelte.dev/repl](https://svelte.dev/repl)` - } - }; + const files = {}; components.forEach(component => { - const file = `${component.name}.${component.type}`; - if (!component.source.trim()) { - throw new Error(`GitHub does not allow saving gists with empty files - ${file}`); - } - files[file] = { content: component.source }; - }); - - const r = await fetch(`https://api.github.com/gists`, { - method: 'POST', - headers: { - Authorization: `token ${user.token}` - }, - body: JSON.stringify({ - description: name, - files, - public: false - }) + const text = component.source.trim(); + if (!text.length) return; // skip empty file + files[`${component.name}.${component.type}`] = text; }); - const gist = await r.json(); + const [row] = await query(` + insert into gists(user_id, name, files) + values ($1, $2, $3) returning *`, [user.id, name, files]); - send(res, r.status, { - id: gist.id, - description: gist.description, - owner: gist.owner, - html_url: gist.html_url, - files: gist.files + send(res, 201, { + uid: row.uid, + name: row.name, + files: row.files, }); } catch (err) { send(res, 500, { diff --git a/site/src/routes/repl/_components/AppControls/index.svelte b/site/src/routes/repl/_components/AppControls/index.svelte index 179a8e4470..fc4107bfa1 100644 --- a/site/src/routes/repl/_components/AppControls/index.svelte +++ b/site/src/routes/repl/_components/AppControls/index.svelte @@ -26,7 +26,7 @@ return new Promise(f => setTimeout(f, ms)); } - let canSave; + $: Authorization = $user && `Bearer ${$user.token}`; $: canSave = !!$user && !!gist && !!gist.owner && $user.id == gist.owner.id; // comparing number and string function handleKeydown(event) { @@ -57,7 +57,7 @@ try { const r = await fetch(`gist/create`, { method: 'POST', - credentials: 'include', + headers: { Authorization }, body: JSON.stringify({ name, components