As alluded to in #17, I think we need to change how we plan to do auth. At present the API handles all the GitHub OAuth stuff, which is fine if we're a) requesting something that doesn't need authentication (e.g. docs) or b) requesting it in the client, but not both.
There are a couple of places in the app where information about the user or their data is used during SSR, and we could potentially add more in future. The options I see are:
Rewrite those bits to use client-side rendering instead, with the attendant flickering etc
Move responsibility for authentication back to https://svelte.dev, and just use the API for session management
Of these, 2 feels like the correct/future-proof choice. To that end I propose the following:
/session
POST /session with a User object (this happens in the OAuth callback during login) — upserts the User, creates a Session and returns { sessionid, expires }
/session/:uuid
GET /session/:uuid returns { user } (happens in handle, albeit probably with an in-memory LRU cache)
DELETE /session/:uuid deletes the session (aka logs the user out)
The types in question:
type User = {
id: string; // the GitHub user ID
username: string;
name: string;
avatar: string;
token: GitHub.AccessToken;
}
type Session {
uuid: string;
userid: string;
expires: number; // Date.now()
}
The gists and gists/:gistid routes now need the user ID to be included in the request:
/gists
GET /gists?userid=[userid] returns a list of gists belonging to the user with GitHub ID userid
POST /gists?userid=[userid] creates a new gist belong to userid
/gists/:gistid
GET /gists/:gistid (in future this could take a userid param if we wanted to distinguish between public and private gists)
PUT /gists/:gistid?user=[userid]
DELETE /gists/:gistid?user=[userid]
Clearly we can't have just anybody hitting api.svelte.dev/gists/abcdef?user=123456; we will need some form of authorization. This could presumably be as simple as a secret that is known by both svelte.dev and api.svelte.dev (or their local equivalents)?
One thing this doesn't address is the situation in which a GitHub user changes their name or avatar — the old ones will still show up unless we were to re-authenticate with GitHub periodically. I don't know if that's worthwhile.
As alluded to in #17, I think we need to change how we plan to do auth. At present the API handles all the GitHub OAuth stuff, which is fine if we're a) requesting something that doesn't need authentication (e.g. docs) or b) requesting it in the client, but not both.
There are a couple of places in the app where information about the user or their data is used during SSR, and we could potentially add more in future. The options I see are:
Of these, 2 feels like the correct/future-proof choice. To that end I propose the following:
/session
POST /session
with aUser
object (this happens in the OAuth callback during login) — upserts theUser
, creates aSession
and returns{ sessionid, expires }
/session/:uuid
GET /session/:uuid
returns{ user }
(happens inhandle
, albeit probably with an in-memory LRU cache)DELETE /session/:uuid
deletes the session (aka logs the user out)The types in question:
The
gists
andgists/:gistid
routes now need the user ID to be included in the request:/gists
GET /gists?userid=[userid]
returns a list of gists belonging to the user with GitHub IDuserid
POST /gists?userid=[userid]
creates a new gist belong touserid
/gists/:gistid
GET /gists/:gistid
(in future this could take auserid
param if we wanted to distinguish between public and private gists)PUT /gists/:gistid?user=[userid]
DELETE /gists/:gistid?user=[userid]
Clearly we can't have just anybody hitting
api.svelte.dev/gists/abcdef?user=123456
; we will need some form of authorization. This could presumably be as simple as a secret that is known by both svelte.dev and api.svelte.dev (or their local equivalents)?One thing this doesn't address is the situation in which a GitHub user changes their name or avatar — the old ones will still show up unless we were to re-authenticate with GitHub periodically. I don't know if that's worthwhile.