mirror of
https://github.com/graphql-hive/console
synced 2026-05-12 19:58:25 +00:00
* add supertoken container to docker-compose file * yeah I am sorry this one big commit and I am ashamed of it * use logOut function * feat: show header on 404 page * feat: better handling for organization cookie when not authenticated * wrap it * check session within server side props * add is_admin flag user migration * simplify and annotate the config * fix: handle status codes + fix email/password sign up with import from auth0 * no hardcoded env pls * decode process.env * secure update user id mapping via a key * fix: login form * lol we don't need to hit the API * fix: do graphql api authorization via authorization header instead of cookie * implement isAdmin flag * fix: types :) * skipit * yo we can run this * set env variables * disable because it annoys the hell out of me * use the right host * add not about token length * refactor: decode environment variables * feat: store external user id from guthub/google provider in the database * workaround supertokens omitting null values from the token * re-enable check * i have no time for this shit * add missing env variable * fix: email test; missing domain extension * configure pulumi deployment Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com> Co-authored-by: Dotan Simha <dotansimha@gmail.com> * configure pulumi deployment Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com> Co-authored-by: Dotan Simha <dotansimha@gmail.com> * configure pulumi deployment Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com> Co-authored-by: Dotan Simha <dotansimha@gmail.com> * configure pulumi deployment Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com> * fix: env names * fix: link google account to the correct db record * feat: email confirmation emails * ? * bump ts-node * fix types * omit package form the bundle * remove it from dependencies... * add emails apckage to dev deps * resolve eslint issues * remove comments * update dev info + change env variable (no need to expose it on the frontend) * use correct user id lol Co-authored-by: Kamil Kisiela <kamil.kisiela@gmail.com> Co-authored-by: Dotan Simha <dotansimha@gmail.com>
111 lines
3.1 KiB
TypeScript
111 lines
3.1 KiB
TypeScript
import { fetch } from 'cross-undici-fetch';
|
|
import zod from 'zod';
|
|
import { ensureEnv } from './env';
|
|
|
|
const SignUpSignInUserResponseModel = zod.object({
|
|
status: zod.literal('OK'),
|
|
user: zod.object({ email: zod.string(), id: zod.string(), timeJoined: zod.number() }),
|
|
});
|
|
|
|
const signUpUserViaEmail = async (
|
|
email: string,
|
|
password: string
|
|
): Promise<zod.TypeOf<typeof SignUpSignInUserResponseModel>> => {
|
|
const response = await fetch(`${ensureEnv('SUPERTOKENS_CONNECTION_URI')}/recipe/signup`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'content-type': 'application/json; charset=UTF-8',
|
|
'api-key': ensureEnv('SUPERTOKENS_API_KEY'),
|
|
},
|
|
body: JSON.stringify({
|
|
email,
|
|
password,
|
|
}),
|
|
});
|
|
const body = await response.text();
|
|
if (response.status !== 200) {
|
|
throw new Error(`Signup failed. ${response.status}.\n ${body}`);
|
|
}
|
|
|
|
return SignUpSignInUserResponseModel.parse(JSON.parse(body));
|
|
};
|
|
|
|
const createSessionPayload = (superTokensUserId: string, email: string) => ({
|
|
version: '1',
|
|
superTokensUserId,
|
|
externalUserId: null,
|
|
email,
|
|
});
|
|
|
|
const CreateSessionModel = zod.object({
|
|
accessToken: zod.object({
|
|
token: zod.string(),
|
|
}),
|
|
refreshToken: zod.object({
|
|
token: zod.string(),
|
|
}),
|
|
idRefreshToken: zod.object({
|
|
token: zod.string(),
|
|
}),
|
|
});
|
|
|
|
const createSession = async (superTokensUserId: string, email: string) => {
|
|
const sessionData = createSessionPayload(superTokensUserId, email);
|
|
const payload = {
|
|
enableAntiCsrf: false,
|
|
userId: superTokensUserId,
|
|
userDataInDatabase: sessionData,
|
|
userDataInJWT: sessionData,
|
|
};
|
|
|
|
const response = await fetch(`${ensureEnv('SUPERTOKENS_CONNECTION_URI')}/recipe/session`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'content-type': 'application/json; charset=UTF-8',
|
|
'api-key': ensureEnv('SUPERTOKENS_API_KEY'),
|
|
rid: 'session',
|
|
},
|
|
body: JSON.stringify(payload),
|
|
});
|
|
const body = await response.text();
|
|
if (response.status !== 200) {
|
|
throw new Error(`Create session failed. ${response.status}.\n ${body}`);
|
|
}
|
|
|
|
const data = CreateSessionModel.parse(JSON.parse(body));
|
|
|
|
/**
|
|
* These are the required cookies that need to be set.
|
|
*/
|
|
return {
|
|
access_token: data.accessToken.token,
|
|
};
|
|
};
|
|
|
|
type UserID = 'main' | 'extra' | 'admin';
|
|
const password = 'ilikebigturtlesandicannotlie47';
|
|
|
|
export const userEmails: Record<UserID, string> = {
|
|
main: 'main@localhost.localhost',
|
|
extra: 'extra@localhost.localhost',
|
|
admin: 'admin@localhost.localhost',
|
|
};
|
|
|
|
const tokenResponsePromise: Record<UserID, Promise<{ access_token: string }> | null> = {
|
|
main: null,
|
|
extra: null,
|
|
admin: null,
|
|
};
|
|
|
|
async function signUpAndSignInViaEmail(email: string, password: string): Promise<{ access_token: string }> {
|
|
const data = await signUpUserViaEmail(email, password);
|
|
return await createSession(data.user.id, data.user.email);
|
|
}
|
|
|
|
export function authenticate(userId: UserID): Promise<{ access_token: string }> {
|
|
if (!tokenResponsePromise[userId]) {
|
|
tokenResponsePromise[userId] = signUpAndSignInViaEmail(userEmails[userId], password);
|
|
}
|
|
|
|
return tokenResponsePromise[userId]!;
|
|
}
|