Updated authentication.
This commit is contained in:
@@ -1,8 +1,16 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, {
|
||||||
|
useState,
|
||||||
|
useEffect,
|
||||||
|
} from "react";
|
||||||
import { NextPage } from "next";
|
import { NextPage } from "next";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import styled from "styled-components";
|
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";
|
import AdminPageWrapper from "@views/common/AdminPageWrapper";
|
||||||
|
|
||||||
const Main = styled.div`
|
const Main = styled.div`
|
||||||
@@ -30,8 +38,11 @@ const AdminLoginPage: NextPage = () => {
|
|||||||
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
try {
|
try {
|
||||||
const token = await generateToken(username, password);
|
const { access, refresh } = await generateToken(username, password);
|
||||||
setTokenCookie(token);
|
|
||||||
|
setAccessTokenCookie(access);
|
||||||
|
setRefreshTokenCookie(refresh);
|
||||||
|
|
||||||
router.push(next);
|
router.push(next);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError("Failed to log in!");
|
setError("Failed to log in!");
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { NextPage } from "next";
|
import { NextPage } from "next";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { deleteTokenCookie } from "@utils/auth";
|
import { deleteTokenCookies } from "@utils/auth";
|
||||||
|
|
||||||
const AdminLogoutPage: NextPage = () => {
|
const AdminLogoutPage: NextPage = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
// client-side-only code
|
// client-side-only code
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
deleteTokenCookie();
|
deleteTokenCookies();
|
||||||
router.push("/admin/login");
|
router.push("/admin/login");
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
+52
-18
@@ -1,46 +1,80 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
|
|
||||||
const tokenUrl = `${process.env.NEXT_PUBLIC_API_URL}/api-token-auth/`;
|
const tokenUrl = `${process.env.NEXT_PUBLIC_API_URL}/token/`;
|
||||||
const checkUrl = `${process.env.NEXT_PUBLIC_API_URL}/api-token-verify/`;
|
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<string> {
|
export async function generateToken(username: string, password: string): Promise<{"access":string, "refresh":string}> {
|
||||||
const resp = await axios.post(tokenUrl, {
|
const resp = await axios.post(tokenUrl, {
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
});
|
});
|
||||||
return resp.data.token;
|
return {
|
||||||
|
"access": resp.data.access,
|
||||||
|
"refresh": resp.data.refresh,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setTokenCookie(token: string): void {
|
export function setAccessTokenCookie(access_token: string): void {
|
||||||
Cookies.set("jwt", token);
|
Cookies.set("jwt_access", access_token);
|
||||||
Cookies.set("jwt", token, { domain: ".sahkoinsinoorikilta.fi" });
|
Cookies.set("jwt_access", access_token, { domain: ".sahkoinsinoorikilta.fi" });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getTokenCookie(): string {
|
export function setRefreshTokenCookie(refresh_token: string): void {
|
||||||
return Cookies.get("jwt");
|
Cookies.set("jwt_refresh", refresh_token);
|
||||||
|
Cookies.set("jwt_refresh", refresh_token, { domain: ".sahkoinsinoorikilta.fi" });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteTokenCookie(): void {
|
export function getAccessTokenCookie(): string {
|
||||||
Cookies.remove("jwt", { domain: ".sahkoinsinoorikilta.fi" });
|
return Cookies.get("jwt_access");
|
||||||
Cookies.remove("jwt");
|
}
|
||||||
|
|
||||||
|
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<boolean> {
|
export async function isAuthenticated(): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const token = getTokenCookie();
|
const token = getAccessTokenCookie();
|
||||||
await axios.post(checkUrl, {
|
|
||||||
|
await axios.post(checkUrl, {
|
||||||
token,
|
token,
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// remove the cookie since it's invalid
|
return refreshToken();
|
||||||
deleteTokenCookie();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function refreshToken(): Promise<boolean> {
|
||||||
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAuthHeader(): string {
|
export function getAuthHeader(): string {
|
||||||
const jwt = getTokenCookie();
|
const jwt = getAccessTokenCookie();
|
||||||
return `JWT ${jwt}`;
|
return `Bearer ${jwt}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
* Test if the user is redirected to login when JWT token is invalid.
|
||||||
*/
|
*/
|
||||||
const setCookie = ClientFunction(() => {
|
const setCookie = ClientFunction(() => {
|
||||||
document.cookie = "jwt=FOOBAR";
|
document.cookie = "jwt_access=FOOBAR";
|
||||||
});
|
});
|
||||||
await setCookie();
|
await setCookie();
|
||||||
await t.navigateTo("/admin/events");
|
await t.navigateTo("/admin/events");
|
||||||
|
|||||||
+13
-13
@@ -27,7 +27,7 @@ export const doLogin = async (t: TestController) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export async function generateToken(): Promise<string> {
|
export async function generateToken(): Promise<string> {
|
||||||
const tokenUrl = `${API_URL}/api-token-auth/`;
|
const tokenUrl = `${API_URL}/token/`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const resp = await axios.post(tokenUrl, {
|
const resp = await axios.post(tokenUrl, {
|
||||||
@@ -43,11 +43,11 @@ export async function generateToken(): Promise<string> {
|
|||||||
|
|
||||||
const eventURL = `${API_URL}/events/`;
|
const eventURL = `${API_URL}/events/`;
|
||||||
|
|
||||||
export async function createEvent(data, jwt: string) {
|
export async function createEvent(data, jwt_access: string) {
|
||||||
try {
|
try {
|
||||||
const resp = await axios.post(eventURL, data, {
|
const resp = await axios.post(eventURL, data, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `JWT ${jwt}`,
|
Authorization: `Bearer ${jwt_access}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return resp.data;
|
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 {
|
try {
|
||||||
const resp = await axios.delete(`${eventURL}${id}/`, {
|
const resp = await axios.delete(`${eventURL}${id}/`, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `JWT ${jwt}`,
|
Authorization: `Bearer ${jwt_access}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return resp.data;
|
return resp.data;
|
||||||
@@ -73,11 +73,11 @@ export async function deleteEvent(id: string, jwt: string) {
|
|||||||
|
|
||||||
const formURL = `${API_URL}/signupForm/`;
|
const formURL = `${API_URL}/signupForm/`;
|
||||||
|
|
||||||
export async function createForm(data, jwt: string) {
|
export async function createForm(data, jwt_access: string) {
|
||||||
try {
|
try {
|
||||||
const resp = await axios.post(formURL, data, {
|
const resp = await axios.post(formURL, data, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `JWT ${jwt}`,
|
Authorization: `Bearer ${jwt_access}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return resp.data;
|
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 {
|
try {
|
||||||
const resp = await axios.delete(`${formURL}${id}/`, {
|
const resp = await axios.delete(`${formURL}${id}/`, {
|
||||||
headers: {
|
headers: {
|
||||||
Authorization: `JWT ${jwt}`,
|
Authorization: `Bearer ${jwt_access}`,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
return resp.data;
|
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({
|
createForm({
|
||||||
title_fi: "Testi Ilmo",
|
title_fi: "Testi Ilmo",
|
||||||
title_en: "Test Signup",
|
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({
|
createEvent({
|
||||||
tags: [1],
|
tags: [1],
|
||||||
visible: true,
|
visible: true,
|
||||||
@@ -153,7 +153,7 @@ export const generateTestEvent = async (formIds = [], jwt: string) => (
|
|||||||
signupForm: formIds,
|
signupForm: formIds,
|
||||||
signup_id: formIds,
|
signup_id: formIds,
|
||||||
tag_id: [1],
|
tag_id: [1],
|
||||||
}, jwt)
|
}, jwt_access)
|
||||||
);
|
);
|
||||||
|
|
||||||
export const sleep = async (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
export const sleep = async (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
|
||||||
|
|||||||
Reference in New Issue
Block a user