From fab3479ad0d5da368095d70ae746ee39bc10a2d1 Mon Sep 17 00:00:00 2001 From: Ojakoo Date: Mon, 4 Jul 2022 09:27:26 +0300 Subject: [PATCH 1/4] Added fopas --- src/views/FreshmenPage/FreshmenPageHero.tsx | 6 ++++++ src/views/FreshmenPage/FreshmenPageView.tsx | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/views/FreshmenPage/FreshmenPageHero.tsx b/src/views/FreshmenPage/FreshmenPageHero.tsx index 13d33c9..948c0ba 100644 --- a/src/views/FreshmenPage/FreshmenPageHero.tsx +++ b/src/views/FreshmenPage/FreshmenPageHero.tsx @@ -11,6 +11,12 @@ const FreshmenPageHero: React.FC = () => ( /> + + (
Killan Fuksiopas
+ + + +

- Ennen opintojen alkua on hyvä tutustua killan fuksioppaaseen. Tulette saamaan sen postitse ja se linkataan tähän heti kun se on julkaistu + Ennen opintojen alkua on hyvä tutustua killan fuksioppaaseen. Sitä pääset selailemaan tästä.


Telegram?
From 9005c3dd93bd632fc1aaa978baf97d91d4463f07 Mon Sep 17 00:00:00 2001 From: Ojakoo Date: Mon, 4 Jul 2022 11:13:02 +0300 Subject: [PATCH 2/4] Updated authentication. --- src/pages/admin/login.tsx | 19 ++++++-- src/pages/admin/logout.tsx | 4 +- src/utils/auth.ts | 70 ++++++++++++++++++++++-------- tests/testcafe/admin/login.test.ts | 2 +- tests/testcafe/utils.ts | 26 +++++------ 5 files changed, 83 insertions(+), 38 deletions(-) diff --git a/src/pages/admin/login.tsx b/src/pages/admin/login.tsx index 90eb3cc..b619689 100644 --- a/src/pages/admin/login.tsx +++ b/src/pages/admin/login.tsx @@ -1,8 +1,16 @@ -import React, { useState, useEffect } from "react"; +import React, { + useState, + useEffect, +} from "react"; import { NextPage } from "next"; import { useRouter } from "next/router"; import styled from "styled-components"; -import { generateToken, setTokenCookie, isAuthenticated } from "@utils/auth"; +import { + generateToken, + setAccessTokenCookie, + setRefreshTokenCookie, + isAuthenticated, +} from "@utils/auth"; import AdminPageWrapper from "@views/common/AdminPageWrapper"; const Main = styled.div` @@ -30,8 +38,11 @@ const AdminLoginPage: NextPage = () => { const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); try { - const token = await generateToken(username, password); - setTokenCookie(token); + const { access, refresh } = await generateToken(username, password); + + setAccessTokenCookie(access); + setRefreshTokenCookie(refresh); + router.push(next); } catch (err) { setError("Failed to log in!"); diff --git a/src/pages/admin/logout.tsx b/src/pages/admin/logout.tsx index 9c506ef..6b548f5 100644 --- a/src/pages/admin/logout.tsx +++ b/src/pages/admin/logout.tsx @@ -1,12 +1,12 @@ import { NextPage } from "next"; import { useRouter } from "next/router"; -import { deleteTokenCookie } from "@utils/auth"; +import { deleteTokenCookies } from "@utils/auth"; const AdminLogoutPage: NextPage = () => { const router = useRouter(); // client-side-only code if (typeof window !== "undefined") { - deleteTokenCookie(); + deleteTokenCookies(); router.push("/admin/login"); } return null; diff --git a/src/utils/auth.ts b/src/utils/auth.ts index 4300fff..e425fe9 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -1,46 +1,80 @@ import axios from "axios"; import Cookies from "js-cookie"; -const tokenUrl = `${process.env.NEXT_PUBLIC_API_URL}/api-token-auth/`; -const checkUrl = `${process.env.NEXT_PUBLIC_API_URL}/api-token-verify/`; +const tokenUrl = `${process.env.NEXT_PUBLIC_API_URL}/token/`; +const checkUrl = `${process.env.NEXT_PUBLIC_API_URL}/token/verify/`; +const refreshUrl = `${process.env.NEXT_PUBLIC_API_URL}/token/refresh/`; -export async function generateToken(username: string, password: string): Promise { +export async function generateToken(username: string, password: string): Promise<{"access":string, "refresh":string}> { const resp = await axios.post(tokenUrl, { username, password, }); - return resp.data.token; + return { + "access": resp.data.access, + "refresh": resp.data.refresh, + }; } -export function setTokenCookie(token: string): void { - Cookies.set("jwt", token); - Cookies.set("jwt", token, { domain: ".sahkoinsinoorikilta.fi" }); +export function setAccessTokenCookie(access_token: string): void { + Cookies.set("jwt_access", access_token); + Cookies.set("jwt_access", access_token, { domain: ".sahkoinsinoorikilta.fi" }); } -export function getTokenCookie(): string { - return Cookies.get("jwt"); +export function setRefreshTokenCookie(refresh_token: string): void { + Cookies.set("jwt_refresh", refresh_token); + Cookies.set("jwt_refresh", refresh_token, { domain: ".sahkoinsinoorikilta.fi" }); } -export function deleteTokenCookie(): void { - Cookies.remove("jwt", { domain: ".sahkoinsinoorikilta.fi" }); - Cookies.remove("jwt"); +export function getAccessTokenCookie(): string { + return Cookies.get("jwt_access"); +} + +export function getRefreshTokenCookie(): string { + return Cookies.get("jwt_refresh"); +} + +export function deleteTokenCookies(): void { + Cookies.remove("jwt_access", { domain: ".sahkoinsinoorikilta.fi" }); + Cookies.remove("jwt_access"); + Cookies.remove("jwt_refresh", { domain: ".sahkoinsinoorikilta.fi" }); + Cookies.remove("jwt_refresh"); } export async function isAuthenticated(): Promise { try { - const token = getTokenCookie(); - await axios.post(checkUrl, { + const token = getAccessTokenCookie(); + + await axios.post(checkUrl, { token, }); + return true; } catch (err) { - // remove the cookie since it's invalid - deleteTokenCookie(); + return refreshToken(); + } +} + +export async function refreshToken(): Promise { + try { + const refresh = getRefreshTokenCookie(); + if (refresh) { + const resp = await axios.post(refreshUrl, { + refresh, + }); + + setAccessTokenCookie(resp.data.access); + + return true; + } + return false; + } catch (err) { + deleteTokenCookies(); return false; } } export function getAuthHeader(): string { - const jwt = getTokenCookie(); - return `JWT ${jwt}`; + const jwt = getAccessTokenCookie(); + return `Bearer ${jwt}`; } diff --git a/tests/testcafe/admin/login.test.ts b/tests/testcafe/admin/login.test.ts index 13e0797..5eabb67 100644 --- a/tests/testcafe/admin/login.test.ts +++ b/tests/testcafe/admin/login.test.ts @@ -39,7 +39,7 @@ test("User is redirected to login when JWT token is invalid", async (t) => { * Test if the user is redirected to login when JWT token is invalid. */ const setCookie = ClientFunction(() => { - document.cookie = "jwt=FOOBAR"; + document.cookie = "jwt_access=FOOBAR"; }); await setCookie(); await t.navigateTo("/admin/events"); diff --git a/tests/testcafe/utils.ts b/tests/testcafe/utils.ts index efee7e3..ddd760b 100644 --- a/tests/testcafe/utils.ts +++ b/tests/testcafe/utils.ts @@ -27,7 +27,7 @@ export const doLogin = async (t: TestController) => { }; export async function generateToken(): Promise { - const tokenUrl = `${API_URL}/api-token-auth/`; + const tokenUrl = `${API_URL}/token/`; try { const resp = await axios.post(tokenUrl, { @@ -43,11 +43,11 @@ export async function generateToken(): Promise { const eventURL = `${API_URL}/events/`; -export async function createEvent(data, jwt: string) { +export async function createEvent(data, jwt_access: string) { try { const resp = await axios.post(eventURL, data, { headers: { - Authorization: `JWT ${jwt}`, + Authorization: `Bearer ${jwt_access}`, }, }); return resp.data; @@ -57,11 +57,11 @@ export async function createEvent(data, jwt: string) { } } -export async function deleteEvent(id: string, jwt: string) { +export async function deleteEvent(id: string, jwt_access: string) { try { const resp = await axios.delete(`${eventURL}${id}/`, { headers: { - Authorization: `JWT ${jwt}`, + Authorization: `Bearer ${jwt_access}`, }, }); return resp.data; @@ -73,11 +73,11 @@ export async function deleteEvent(id: string, jwt: string) { const formURL = `${API_URL}/signupForm/`; -export async function createForm(data, jwt: string) { +export async function createForm(data, jwt_access: string) { try { const resp = await axios.post(formURL, data, { headers: { - Authorization: `JWT ${jwt}`, + Authorization: `Bearer ${jwt_access}`, }, }); return resp.data; @@ -87,11 +87,11 @@ export async function createForm(data, jwt: string) { } } -export async function deleteForm(id: string, jwt: string) { +export async function deleteForm(id: string, jwt_access: string) { try { const resp = await axios.delete(`${formURL}${id}/`, { headers: { - Authorization: `JWT ${jwt}`, + Authorization: `Bearer ${jwt_access}`, }, }); return resp.data; @@ -101,7 +101,7 @@ export async function deleteForm(id: string, jwt: string) { } } -export const generateTestForm = async (jwt: string) => ( +export const generateTestForm = async (jwt_access: string) => ( createForm({ title_fi: "Testi Ilmo", title_en: "Test Signup", @@ -132,10 +132,10 @@ export const generateTestForm = async (jwt: string) => ( }, }, }, - }, jwt) + }, jwt_access) ); -export const generateTestEvent = async (formIds = [], jwt: string) => ( +export const generateTestEvent = async (formIds = [], jwt_access: string) => ( createEvent({ tags: [1], visible: true, @@ -153,7 +153,7 @@ export const generateTestEvent = async (formIds = [], jwt: string) => ( signupForm: formIds, signup_id: formIds, tag_id: [1], - }, jwt) + }, jwt_access) ); export const sleep = async (ms: number) => new Promise((resolve) => setTimeout(resolve, ms)); From 2ab8185a5903c56bc7277f32dde2d9769f5610c6 Mon Sep 17 00:00:00 2001 From: Ojakoo Date: Mon, 4 Jul 2022 11:14:21 +0300 Subject: [PATCH 3/4] Forgot to add this --- src/utils/auth.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils/auth.ts b/src/utils/auth.ts index e425fe9..42e2b1b 100644 --- a/src/utils/auth.ts +++ b/src/utils/auth.ts @@ -75,6 +75,6 @@ export async function refreshToken(): Promise { } export function getAuthHeader(): string { - const jwt = getAccessTokenCookie(); - return `Bearer ${jwt}`; + const jwt_access = getAccessTokenCookie(); + return `Bearer ${jwt_access}`; } From a1434b84be9ce85d08ad594824db5b9d64104e18 Mon Sep 17 00:00:00 2001 From: Ojakoo Date: Tue, 5 Jul 2022 18:57:29 +0300 Subject: [PATCH 4/4] Fixed access token generation for testcafe --- tests/testcafe/admin/create-event.test.ts | 6 +++--- tests/testcafe/admin/create-signup.test.ts | 5 +++-- tests/testcafe/signupToEvent.test.ts | 6 +++--- tests/testcafe/utils.ts | 4 ++-- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/testcafe/admin/create-event.test.ts b/tests/testcafe/admin/create-event.test.ts index 8df7f6b..41f0917 100644 --- a/tests/testcafe/admin/create-event.test.ts +++ b/tests/testcafe/admin/create-event.test.ts @@ -1,6 +1,6 @@ import { Selector } from "testcafe"; import { - getSiteRoot, getPageUrl, generateTestForm, deleteEvent, deleteForm, doLogin, generateToken, getPostRequestLogger, + getSiteRoot, getPageUrl, generateTestForm, deleteEvent, deleteForm, doLogin, generateAccessToken, getPostRequestLogger, } from "../utils"; const LOGGER = getPostRequestLogger("events/"); @@ -8,12 +8,12 @@ const LOGGER = getPostRequestLogger("events/"); fixture`Admin events`.page(`${getSiteRoot()}/admin/events`) .requestHooks(LOGGER) .before(async (ctx) => { - const token = await generateToken(); + const token = await generateAccessToken(); const form = await generateTestForm(token); ctx.formId = form.id; }) .after(async (ctx) => { - const token = await generateToken(); + const token = await generateAccessToken(); await deleteEvent(ctx.eventId, token); await deleteForm(ctx.formId, token); }); diff --git a/tests/testcafe/admin/create-signup.test.ts b/tests/testcafe/admin/create-signup.test.ts index b272b3e..afe5767 100644 --- a/tests/testcafe/admin/create-signup.test.ts +++ b/tests/testcafe/admin/create-signup.test.ts @@ -1,6 +1,6 @@ import { Selector } from "testcafe"; import { - getSiteRoot, getPageUrl, deleteForm, doLogin, generateToken, getPostRequestLogger, + getSiteRoot, getPageUrl, deleteForm, doLogin, generateAccessToken, getPostRequestLogger, } from "../utils"; const LOGGER = getPostRequestLogger("signupForm/"); @@ -8,7 +8,8 @@ const LOGGER = getPostRequestLogger("signupForm/"); fixture`Admin signup form`.page(`${getSiteRoot()}/admin/signups`) .requestHooks(LOGGER) .after(async (ctx) => { - const token = await generateToken(); + const token = await generateAccessToken(); + await deleteForm(ctx.formId, token); }); diff --git a/tests/testcafe/signupToEvent.test.ts b/tests/testcafe/signupToEvent.test.ts index e447d89..5205188 100644 --- a/tests/testcafe/signupToEvent.test.ts +++ b/tests/testcafe/signupToEvent.test.ts @@ -1,18 +1,18 @@ import { Selector } from "testcafe"; import { - getSiteRoot, getPageUrl, generateTestEvent, generateTestForm, deleteEvent, deleteForm, generateToken, + getSiteRoot, getPageUrl, generateTestEvent, generateTestForm, deleteEvent, deleteForm, generateAccessToken, } from "./utils"; fixture`Event signup`.page(getSiteRoot()) .before(async (ctx) => { - const token = await generateToken(); + const token = await generateAccessToken(); const form = await generateTestForm(token); const event = await generateTestEvent([form.id], token); ctx.eventId = event.id; ctx.formId = form.id; }) .after(async (ctx) => { - const token = await generateToken(); + const token = await generateAccessToken(); await deleteEvent(ctx.eventId, token); await deleteForm(ctx.formId, token); }); diff --git a/tests/testcafe/utils.ts b/tests/testcafe/utils.ts index ddd760b..e734fd7 100644 --- a/tests/testcafe/utils.ts +++ b/tests/testcafe/utils.ts @@ -26,7 +26,7 @@ export const doLogin = async (t: TestController) => { await t.click(Selector("#login-submit")); }; -export async function generateToken(): Promise { +export async function generateAccessToken(): Promise { const tokenUrl = `${API_URL}/token/`; try { @@ -34,7 +34,7 @@ export async function generateToken(): Promise { username: USERNAME, password: PASSWORD, }); - return resp.data.token; + return resp.data.access; } catch (err) { console.error(err); throw err;