diff --git a/src/login.ts b/src/login.ts index b6ff55d..071f19c 100644 --- a/src/login.ts +++ b/src/login.ts @@ -8,7 +8,21 @@ import { request } from 'http'; import { get_setting } from './setting'; import { IUser } from './model/mod'; -const loginTokenName = 'access_token' +type PayloadInfo = { + username:string, + permission:string[] +} + +export type UserState = { + user?:PayloadInfo +}; + +const isUserState = (obj:object|string):obj is PayloadInfo =>{ + if(typeof obj ==="string") return false; + return 'username' in obj && 'permission' in obj && (obj as {permission:unknown}).permission instanceof Array; +} + +export const loginTokenName = 'access_token' export const getAdminCookieValue = ()=>{ const setting = get_setting(); @@ -26,27 +40,22 @@ export const createLoginMiddleware = (knex: Knex)=>{ const secretKey = setting.jwt_secretkey; const body = ctx.request.body; if(!('username' in body)||!('password' in body)){ - sendError(400,"invalid form : username or password is not found in query."); - return; + return sendError(400,"invalid form : username or password is not found in query."); } const username = body['username']; const password = body['password']; if(typeof username !== "string" || typeof password !== "string"){ - sendError(400,"invalid form : username or password is not string") - return; + return sendError(400,"invalid form : username or password is not string") } if(setting.forbid_remote_admin_login && username === "admin"){ - sendError(403,"forbid remote admin login"); - return; + return sendError(403,"forbid remote admin login"); } const user = await userController.findUser(username); if(user === undefined){ - sendError(401,"not authorized"); - return; + return sendError(401,"not authorized"); } if(!user.password.check_password(password)){ - sendError(401,"not authorized"); - return; + return sendError(401,"not authorized"); } const userPermission = await user.get_permissions(); const payload = sign({ @@ -64,15 +73,21 @@ export const LogoutMiddleware = (ctx:Koa.Context,next:Koa.Next)=>{ ctx.body = {ok:true}; return; } -export const UserMiddleWare = async (ctx:Koa.Context,next:Koa.Next)=>{ +export const UserMiddleWare = async (ctx:Koa.ParameterizedContext,next:Koa.Next)=>{ const secretKey = get_setting().jwt_secretkey; const payload = ctx.cookies.get(loginTokenName); if(payload == undefined){ ctx.state['user'] = undefined; return await next(); } - ctx.state['user'] = verify(payload,secretKey); - await next(); + const o = verify(payload,secretKey); + if(isUserState(o)){ + ctx.state.user = o; + return await next(); + } + else{ + console.error("invalid token detected"); + } } export const getAdmin = async(knex : Knex)=>{ diff --git a/src/route/contents.ts b/src/route/contents.ts index 5894ae7..a135bda 100644 --- a/src/route/contents.ts +++ b/src/route/contents.ts @@ -12,8 +12,7 @@ const ContentIDHandler = (controller: ContentAccessor) => async (ctx: Context,ne const num = Number.parseInt(ctx.params['num']); let content = await controller.findById(num,true); if (content == undefined){ - sendError(404,"content does not exist."); - return; + return sendError(404,"content does not exist."); } ctx.body = content; ctx.type = 'json'; @@ -23,8 +22,7 @@ const ContentTagIDHandler = (controller: ContentAccessor) => async (ctx: Context const num = Number.parseInt(ctx.params['num']); let content = await controller.findById(num,true); if (content == undefined){ - sendError(404,"content does not exist."); - return; + return sendError(404,"content does not exist."); } ctx.body = content.tags || []; ctx.type = 'json'; @@ -36,13 +34,12 @@ const ContentQueryHandler = (controller : ContentAccessor) => async (ctx: Contex const content_type:string|undefined = ctx.query['content_type']; const offset = ParseQueryNumber(ctx.query['offset']); if(limit === NaN || cursor === NaN || offset === NaN){ - sendError(400,"parameter limit, cursor or offset is not a number"); + return sendError(400,"parameter limit, cursor or offset is not a number"); } const allow_tag = ParseQueryArray(ctx.query['allow_tag[]']); let [ok,use_offset] = ParseQueryBoolean(ctx.query['use_offset']); if(!ok){ - sendError(400,"use_offset must be true or false."); - return; + return sendError(400,"use_offset must be true or false."); } const option :QueryListOption = { limit: limit, @@ -61,10 +58,10 @@ const ContentQueryHandler = (controller : ContentAccessor) => async (ctx: Contex const UpdateContentHandler = (controller : ContentAccessor) => async (ctx: Context, next: Next) => { const num = Number.parseInt(ctx.params['num']); if(ctx.request.type !== 'json'){ - sendError(400,"update fail. invalid content type: it is not json."); + return sendError(400,"update fail. invalid content type: it is not json."); } if(typeof ctx.request.body !== "object"){ - sendError(400,"update fail. invalid argument: not"); + return sendError(400,"update fail. invalid argument: not"); } const content_desc: Partial & {id: number} = { id:num,...ctx.request.body @@ -76,8 +73,7 @@ const UpdateContentHandler = (controller : ContentAccessor) => async (ctx: Conte const CreateContentHandler = (controller : ContentAccessor) => async (ctx: Context, next: Next) => { const content_desc = ctx.request.body; if(!isContentContent(content_desc)){ - sendError(400,"it is not a valid format"); - return; + return sendError(400,"it is not a valid format"); } const id = await controller.add(content_desc); ctx.body = JSON.stringify(id); @@ -87,13 +83,12 @@ const AddTagHandler = (controller: ContentAccessor)=>async (ctx: Context, next: let tag_name = ctx.params['tag']; const num = Number.parseInt(ctx.params['num']); if(typeof tag_name === undefined){ - sendError(400,"??? Unreachable"); + return sendError(400,"??? Unreachable"); } tag_name = String(tag_name); const c = await controller.findById(num); if(c === undefined){ - sendError(404); - return; + return sendError(404); } const r = await controller.addTag(c,tag_name); ctx.body = JSON.stringify(r); @@ -103,13 +98,12 @@ const DelTagHandler = (controller: ContentAccessor)=>async (ctx: Context, next: let tag_name = ctx.params['tag']; const num = Number.parseInt(ctx.params['num']); if(typeof tag_name === undefined){ - sendError(400,"?? Unreachable"); + return sendError(400,"?? Unreachable"); } tag_name = String(tag_name); const c = await controller.findById(num); if(c === undefined){ - sendError(404); - return; + return sendError(404); } const r = await controller.delTag(c,tag_name); ctx.body = JSON.stringify(r); @@ -125,8 +119,7 @@ const ContentHandler = (controller : ContentAccessor) => async (ctx:Context, nex const num = Number.parseInt(ctx.params['num']); let content = await controller.findById(num,true); if (content == undefined){ - sendError(404,"content does not exist."); - return; + return sendError(404,"content does not exist."); } const path = join(content.basepath,content.filename); ctx.state['content'] = createContentReferrer(content.content_type,path,content.additional);