Skip to content

Commit

Permalink
refactor: export validation function to separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
shaokeyibb committed Sep 1, 2024
1 parent 689491d commit beebc8a
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 105 deletions.
119 changes: 14 additions & 105 deletions cloudflare-workers/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,10 @@

import { AutoRouter, cors, error } from 'itty-router';
import {
Commenter,
DeleteCommentIDParam,
GetCommentBody,
GetCommentRespBody,
ModifiedCommentBody,
JWTPayload,
OAuthState,
PatchCommentBody,
PatchCommentIDBody,
Expand All @@ -27,105 +26,21 @@ import {
ResponseBody,
} from './types';
import { deleteComment, getComment, getUserOfComment, modifyComment, postComment, registerUser } from './db';
import {
validateSecret,
setCommitHash,
compareCommitHash,
modifyComments,
renameComments,
sendCommentUpdateToTelegram,
} from './administration';
import { setCommitHash, compareCommitHash, modifyComments, renameComments, sendCommentUpdateToTelegram } from './administration';
import { matchCommentCache, purgeAllCommentCache, purgeCommentCache, putCommentCache } from './cache';
import { signJWT, verifyAndDecodeJWT } from './utils';
import { signJWT } from './utils';
import { getAccessToken, getUserInfo } from './oauth';

function validatePath(path: string | undefined): boolean {
if (path === undefined) {
return false;
}

if (!path.startsWith('/')) {
return false;
}

return true;
}

function validateAndDecodePath(path: string | undefined): string | null {
if (path === undefined) {
return null;
}

path = decodeURIComponent(path);

if (!path.startsWith('/')) {
return null;
}

return path;
}

function validateDiff(diff: ModifiedCommentBody['diff']): boolean {
return diff != undefined && diff instanceof Array === true && diff.length !== 0;
}

function validateOffset(offset: PostCommentBody['offset']): boolean {
return offset.start >= 0 && offset.end >= 0 && offset.start < offset.end;
}

function validateComment(comment: PostCommentBody['comment'] | undefined): boolean {
return comment != undefined && comment.length >= 1 && comment.length <= 65535;
}

async function validateAndDecodeAuthorizationToken(env: Env, req: Request): Promise<JWTPayload | null> {
const authorization = req.headers.get('Authorization');

if (!authorization) {
return null;
}

const [scheme, secret] = authorization.split(' ');

if (scheme !== 'Bearer' || !secret) {
return null;
}

let token;
try {
token = (await verifyAndDecodeJWT(secret, env.OAUTH_JWT_SECRET)) as JWTPayload;
} catch (e) {
return null;
}

return token;
}

function validateAdministratorSecret(env: Env, req: Request): boolean {
const authorization = req.headers.get('Authorization');

if (!authorization) {
return false;
}

const [scheme, secret] = authorization.split(' ');

if (scheme !== 'Bearer' || !secret) {
return false;
}

return validateSecret(env, secret);
}

function validateCommitHash(hash: string | undefined): boolean {
return hash != undefined && hash.length > 0;
}

function isSameCommenter(commenter: Commenter | null, token: JWTPayload | null): boolean {
if (commenter === null || token === null) {
return false;
}
return commenter.oauth_provider === token.provider && commenter.oauth_user_id === token.id;
}
import {
isSameCommenter,
validateAdministratorSecret,
validateAndDecodeAuthorizationToken,
validateAndDecodePath,
validateComment,
validateCommitHash,
validateDiff,
validateOffset,
validatePath,
} from './validation';

const { preflight, corsify } = cors({
origin: [
Expand Down Expand Up @@ -153,12 +68,6 @@ const router = AutoRouter({
finally: [corsify],
});

type JWTPayload = {
provider: string;
id: string;
name: string;
};

router.post('/comment/:path', async (req, env, ctx) => {
const params = req.params as GetCommentBody;

Expand Down
6 changes: 6 additions & 0 deletions cloudflare-workers/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,9 @@ export type Commenter = {
oauth_user_id: string;
name: string;
};

export type JWTPayload = {
provider: string;
id: string;
name: string;
};
91 changes: 91 additions & 0 deletions cloudflare-workers/src/validation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { validateSecret } from './administration';
import { Commenter, JWTPayload, ModifiedCommentBody, PostCommentBody } from './types';
import { verifyAndDecodeJWT } from './utils';

export function validatePath(path: string | undefined): boolean {
if (path === undefined) {
return false;
}

if (!path.startsWith('/')) {
return false;
}

return true;
}

export function validateAndDecodePath(path: string | undefined): string | null {
if (path === undefined) {
return null;
}

path = decodeURIComponent(path);

if (!path.startsWith('/')) {
return null;
}

return path;
}

export function validateDiff(diff: ModifiedCommentBody['diff']): boolean {
return diff != undefined && diff instanceof Array === true && diff.length !== 0;
}

export function validateOffset(offset: PostCommentBody['offset']): boolean {
return offset.start >= 0 && offset.end >= 0 && offset.start < offset.end;
}

export function validateComment(comment: PostCommentBody['comment'] | undefined): boolean {
return comment != undefined && comment.length >= 1 && comment.length <= 65535;
}

export async function validateAndDecodeAuthorizationToken(env: Env, req: Request): Promise<JWTPayload | null> {
const authorization = req.headers.get('Authorization');

if (!authorization) {
return null;
}

const [scheme, secret] = authorization.split(' ');

if (scheme !== 'Bearer' || !secret) {
return null;
}

let token;
try {
token = (await verifyAndDecodeJWT(secret, env.OAUTH_JWT_SECRET)) as JWTPayload;
} catch (e) {
return null;
}

return token;
}

export function validateAdministratorSecret(env: Env, req: Request): boolean {
const authorization = req.headers.get('Authorization');

if (!authorization) {
return false;
}

const [scheme, secret] = authorization.split(' ');

if (scheme !== 'Bearer' || !secret) {
return false;
}

return validateSecret(env, secret);
}

export function validateCommitHash(hash: string | undefined): boolean {
return hash != undefined && hash.length > 0;
}

export function isSameCommenter(commenter: Commenter | null, token: JWTPayload | null): boolean {
if (commenter === null || token === null) {
return false;
}
return commenter.oauth_provider === token.provider && commenter.oauth_user_id === token.id;
}

0 comments on commit beebc8a

Please sign in to comment.