refactor: login

This commit is contained in:
monoid 2022-07-06 15:53:40 +09:00
parent 8d20c30d32
commit beafeb7ace

View File

@ -137,7 +137,7 @@ export const createLoginMiddleware = (userController: UserAccessor) =>
ctx.body = { ctx.body = {
username: user.username, username: user.username,
permission: userPermission, permission: userPermission,
accessExpired : (Math.floor(Date.now() / 1000) + accessExpiredTime), accessExpired: (Math.floor(Date.now() / 1000) + accessExpiredTime),
}; };
console.log(`${username} logined`); console.log(`${username} logined`);
return; return;
@ -147,9 +147,11 @@ export const LogoutMiddleware = (ctx: Koa.Context, next: Koa.Next) => {
const setting = get_setting() const setting = get_setting()
ctx.cookies.set(accessTokenName, null); ctx.cookies.set(accessTokenName, null);
ctx.cookies.set(refreshTokenName, null); ctx.cookies.set(refreshTokenName, null);
ctx.body = { ok: true, ctx.body = {
username: "", ok: true,
permission: setting.guest }; username: "",
permission: setting.guest
};
return; return;
}; };
export const createUserMiddleWare = (userController: UserAccessor) => export const createUserMiddleWare = (userController: UserAccessor) =>
@ -166,15 +168,33 @@ export const createUserMiddleWare = (userController: UserAccessor) =>
}; };
const refreshTokenHandler = (cntr: UserAccessor) => const refreshTokenHandler = (cntr: UserAccessor) =>
async (ctx: Koa.Context, fail: Koa.Next, next: Koa.Next) => { async (ctx: Koa.Context, fail: Koa.Next, next: Koa.Next) => {
const payload = ctx.cookies.get(accessTokenName); const accessPayload = ctx.cookies.get(accessTokenName);
const setting = get_setting(); const setting = get_setting();
const secretKey = setting.jwt_secretkey; const secretKey = setting.jwt_secretkey;
const checkRefreshAndUpdate = async () => { if (accessPayload == undefined) {
const payload2 = ctx.cookies.get(refreshTokenName); return await checkRefreshAndUpdate();
if (payload2 === undefined) return await fail(); // refresh token doesn't exist }
else { try {
const o = verify(accessPayload, secretKey);
if (isUserState(o)) {
ctx.state.user = o;
return await next();
} else {
console.error("invalid token detected");
throw new Error("token form invalid");
}
} catch (e) {
if (e instanceof TokenExpiredError) {
return await checkRefreshAndUpdate();
} else throw e;
}
async function checkRefreshAndUpdate() {
const refreshPayload = ctx.cookies.get(refreshTokenName);
if (refreshPayload === undefined) {
return await fail(); // refresh token doesn't exist
} else {
try { try {
const o = verify(payload2, secretKey); const o = verify(refreshPayload, secretKey);
if (isRefreshToken(o)) { if (isRefreshToken(o)) {
const user = await cntr.findUser(o.username); const user = await cntr.findUser(o.username);
if (user === undefined) return await fail(); //already non-existence user if (user === undefined) return await fail(); //already non-existence user
@ -199,28 +219,12 @@ const refreshTokenHandler = (cntr: UserAccessor) =>
} }
return await next(); return await next();
}; };
if (payload == undefined) {
return await checkRefreshAndUpdate();
}
try {
const o = verify(payload, secretKey);
if (isUserState(o)) {
ctx.state.user = o;
return await next();
} else {
console.error("invalid token detected");
throw new Error("token form invalid");
}
} catch (e) {
if (e instanceof TokenExpiredError) {
return await checkRefreshAndUpdate();
} else throw e;
}
}; };
export const createRefreshTokenMiddleware = (cntr: UserAccessor) => export const createRefreshTokenMiddleware = (cntr: UserAccessor) =>
async (ctx: Koa.Context, next: Koa.Next) => { async (ctx: Koa.Context, next: Koa.Next) => {
const handler = refreshTokenHandler(cntr); const handler = refreshTokenHandler(cntr);
const fail = async () => { await handler(ctx, fail, success);
async function fail() {
const user = ctx.state.user as PayloadInfo; const user = ctx.state.user as PayloadInfo;
ctx.body = { ctx.body = {
refresh: false, refresh: false,
@ -228,7 +232,7 @@ export const createRefreshTokenMiddleware = (cntr: UserAccessor) =>
}; };
ctx.type = "json"; ctx.type = "json";
}; };
const success = async () => { async function success() {
const user = ctx.state.user as PayloadInfo; const user = ctx.state.user as PayloadInfo;
ctx.body = { ctx.body = {
...user, ...user,
@ -237,37 +241,36 @@ export const createRefreshTokenMiddleware = (cntr: UserAccessor) =>
}; };
ctx.type = "json"; ctx.type = "json";
}; };
await handler(ctx, fail, success);
}; };
export const resetPasswordMiddleware = (cntr: UserAccessor) => export const resetPasswordMiddleware = (cntr: UserAccessor) =>
async (ctx:Koa.Context, next: Koa.Next) => { async (ctx: Koa.Context, next: Koa.Next) => {
const body = ctx.request.body; const body = ctx.request.body;
if(typeof body !== "object" || !('username' in body)||!('oldpassword' in body) || !('newpassword' in body)){ if (typeof body !== "object" || !('username' in body) || !('oldpassword' in body) || !('newpassword' in body)) {
return sendError(400,"request body is invalid format"); return sendError(400, "request body is invalid format");
} }
const username = body['username']; const username = body['username'];
const oldpw = body['oldpassword']; const oldpw = body['oldpassword'];
const newpw = body['newpassword']; const newpw = body['newpassword'];
if(typeof username !== "string" || typeof oldpw !== "string" || typeof newpw !== "string"){ if (typeof username !== "string" || typeof oldpw !== "string" || typeof newpw !== "string") {
return sendError(400,"request body is invalid format"); return sendError(400, "request body is invalid format");
} }
const user = await cntr.findUser(username); const user = await cntr.findUser(username);
if(user === undefined){ if (user === undefined) {
return sendError(403,"not authorized"); return sendError(403, "not authorized");
} }
if(!user.password.check_password(oldpw)){ if (!user.password.check_password(oldpw)) {
return sendError(403,"not authorized"); return sendError(403, "not authorized");
} }
user.reset_password(newpw); user.reset_password(newpw);
ctx.body = {ok:true} ctx.body = { ok: true }
ctx.type = 'json'; ctx.type = 'json';
} }
export function createLoginRouter(userController: UserAccessor){ export function createLoginRouter(userController: UserAccessor) {
let router = new Router(); let router = new Router();
router.post('/login',createLoginMiddleware(userController)); router.post('/login', createLoginMiddleware(userController));
router.post('/logout',LogoutMiddleware); router.post('/logout', LogoutMiddleware);
router.post('/refresh',createRefreshTokenMiddleware(userController)); router.post('/refresh', createRefreshTokenMiddleware(userController));
router.post('/reset', resetPasswordMiddleware(userController)); router.post('/reset', resetPasswordMiddleware(userController));
return router; return router;
} }