Skip to content

Commit

Permalink
Fix demo (#316)
Browse files Browse the repository at this point in the history
  • Loading branch information
sonic16x authored Nov 19, 2024
1 parent 9bcc253 commit a2ad8bd
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 103 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,4 @@ jobs:
state: success
token: ${{ secrets.GITHUB_TOKEN }}
deployment_id: ${{ steps.deployment.outputs.deployment_id }}
environment_url: ${{ steps.deploy.outputs.deployment-url }}
environment_url: https://pr-${{ steps.pr_number.outputs.pr }}.interslavic-dictionary.pages.dev/
22 changes: 22 additions & 0 deletions src/server/handleOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { corsHeaders } from "./headers";

export function handleOptions (request) {
if (
request.headers.get("Origin") !== null &&
request.headers.get("Access-Control-Request-Method") !== null &&
request.headers.get("Access-Control-Request-Headers") !== null
) {
return new Response(null, {
headers: {
...corsHeaders,
"Access-Control-Allow-Headers": request.headers.get("Access-Control-Request-Headers"),
},
})
} else {
return new Response(null, {
headers: {
Allow: "GET, HEAD, POST, OPTIONS",
},
})
}
}
65 changes: 65 additions & 0 deletions src/server/handleRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { addRow } from "./addRow";
import { checkCaptcha } from "./checkCaptcha";
import { getTableHeader } from "./getTableHeader";
import { googleAuth } from "./googleAuth";
import { handleOptions } from "./handleOptions";
import { responseHeaders } from "./headers";
import { responseError } from "./responseError";
import { validateData } from "./validateData";

export async function handleRequest(request, env) {
if (request.method === "OPTIONS") {
return handleOptions(request)
}

const data = await request.json();
const { pathname } = new URL(request.url);

if (!pathname.startsWith('/api/word-error')) {
return responseError('invalidPath');
}

const dataIsValid = validateData(data);

if (!dataIsValid) {
return responseError('invalidData');
}

const ip = request.headers.get('CF-Connecting-IP');
const captchaIsOk = await checkCaptcha(env.CLOUDFLARE_CAPTCHA_SECRET_KEY, data.captchaToken, ip);

if (!captchaIsOk) {
return responseError('invalidCaptcha');
}

const googleAccessToken = await googleAuth(env.GOOGLE_SERVICE_ACCOUNT_EMAIL, env.GOOGLE_PRIVATE_KEY);

if (!googleAccessToken) {
return responseError('invalidGoogleAccessToken');
}

const tableHeader = await getTableHeader(env.GOOGLE_WORD_ERRORS_TABLE_ID, googleAccessToken);

if (!tableHeader || !tableHeader.length) {
return responseError('invalidTableHeader');
}

const newRow = tableHeader.map((fieldName) => {
if (fieldName === 'timestamp') {
return Math.round(new Date().getTime() / 1000).toString();
}

return data[fieldName];
});

const addRowResponse = await addRow(env.GOOGLE_WORD_ERRORS_TABLE_ID, newRow, googleAccessToken);

if (addRowResponse.status === 200) {
return new Response(JSON.stringify({ error: null }), {
status: addRowResponse.status,
headers: responseHeaders,
});
} else {
return responseError('invalidAddRow');
}
}
10 changes: 10 additions & 0 deletions src/server/headers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,HEAD,POST,OPTIONS',
'Access-Control-Max-Age': '86400',
}

export const responseHeaders = {
...corsHeaders,
'Content-Type': 'application/json',
}
104 changes: 2 additions & 102 deletions src/server/index.ts
Original file line number Diff line number Diff line change
@@ -1,105 +1,5 @@
import { addRow } from 'server/addRow';
import { checkCaptcha } from 'server/checkCaptcha';
import { getTableHeader } from 'server/getTableHeader';
import { googleAuth } from 'server/googleAuth';
import { validateData } from 'server/validateData';


const corsHeaders = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET,HEAD,POST,OPTIONS',
'Access-Control-Max-Age': '86400',
}

const responseHeaders = {
...corsHeaders,
'Content-Type': 'application/json',
}

function responseError(error) {
return new Response(JSON.stringify({ error }), {
status: 500,
headers: responseHeaders,
});
}

function handleOptions (request) {
if (
request.headers.get("Origin") !== null &&
request.headers.get("Access-Control-Request-Method") !== null &&
request.headers.get("Access-Control-Request-Headers") !== null
) {
return new Response(null, {
headers: {
...corsHeaders,
"Access-Control-Allow-Headers": request.headers.get("Access-Control-Request-Headers"),
},
})
} else {
return new Response(null, {
headers: {
Allow: "GET, HEAD, POST, OPTIONS",
},
})
}
}

async function handleRequest(request, env) {
if (request.method === "OPTIONS") {
return handleOptions(request)
}

const data = await request.json();
const { pathname } = new URL(request.url);

if (!pathname.startsWith('/api/word-error')) {
return responseError('invalidPath');
}

const dataIsValid = validateData(data);

if (!dataIsValid) {
return responseError('invalidData');
}

const ip = request.headers.get('CF-Connecting-IP');
const captchaIsOk = await checkCaptcha(env.GOOGLE_CAPTCHA_SECRET_KEY, data.captchaToken, ip);

if (!captchaIsOk) {
return responseError('invalidCaptcha');
}

const googleAccessToken = await googleAuth(env.GOOGLE_SERVICE_ACCOUNT_EMAIL, env.GOOGLE_PRIVATE_KEY);

if (!googleAccessToken) {
return responseError('invalidGoogleAccessToken');
}

const tableHeader = await getTableHeader(env.GOOGLE_WORD_ERRORS_TABLE_ID, googleAccessToken);

if (!tableHeader || !tableHeader.length) {
return responseError('invalidTableHeader');
}

const newRow = tableHeader.map((fieldName) => {
if (fieldName === 'timestamp') {
return Math.round(new Date().getTime() / 1000).toString();
}

return data[fieldName];
});

const addRowResponse = await addRow(env.GOOGLE_WORD_ERRORS_TABLE_ID, newRow, googleAccessToken);

if (addRowResponse.status === 200) {
return new Response(JSON.stringify({ error: null }), {
status: addRowResponse.status,
headers: responseHeaders,
});
} else {
return responseError('invalidAddRow');
}
}
import { handleRequest } from "./handleRequest";
import { responseError } from "./responseError";

export default {
async fetch(request, env) {
Expand Down
8 changes: 8 additions & 0 deletions src/server/responseError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { responseHeaders } from "./headers";

export function responseError(error) {
return new Response(JSON.stringify({ error }), {
status: 500,
headers: responseHeaders,
});
}

0 comments on commit a2ad8bd

Please sign in to comment.