-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
allow users to suggest new words to add to the list
- Loading branch information
Showing
6 changed files
with
372 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -168,6 +168,6 @@ dist | |
|
||
# wrangler project | ||
|
||
# .dev.vars | ||
.dev.vars | ||
|
||
.wrangler |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
-- Migration number: 0002 2024-09-10T16:48:10.681Z | ||
|
||
-- User-provided suggestions for words to be added to the main list. | ||
CREATE TABLE suggestions ( | ||
-- randomly-generated identifier | ||
id TEXT PRIMARY KEY, | ||
|
||
-- The word. | ||
word TEXT, | ||
|
||
-- The definition. | ||
def TEXT, | ||
|
||
-- The user who submitted the suggestion. | ||
author TEXT, | ||
|
||
-- When definition was submitted, as a 64-bit integer number of milliseconds | ||
-- since the unix epoch. | ||
timestamp INT, | ||
|
||
-- 0 means pending | ||
-- 1 means accepted | ||
-- -1 means rejected | ||
status INT, | ||
|
||
-- When a moderator accepts or rejects a suggestion, they may choose | ||
-- to leave a message explaining their choice. | ||
moderator_note Text | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
// Copied from https://developers.cloudflare.com/workers/examples/basic-auth/ | ||
|
||
import { Buffer } from "node:buffer"; | ||
|
||
const encoder = new TextEncoder(); | ||
|
||
/** | ||
* Protect against timing attacks by safely comparing values using `timingSafeEqual`. | ||
* Refer to https://developers.cloudflare.com/workers/runtime-apis/web-crypto/#timingsafeequal for more details | ||
* @param {string} a | ||
* @param {string} b | ||
* @returns {boolean} | ||
*/ | ||
function timingSafeEqual(a, b) { | ||
const aBytes = encoder.encode(a); | ||
const bBytes = encoder.encode(b); | ||
|
||
if (aBytes.byteLength !== bBytes.byteLength) { | ||
// Strings must be the same length in order to compare | ||
// with crypto.subtle.timingSafeEqual | ||
return false; | ||
} | ||
|
||
return crypto.subtle.timingSafeEqual(aBytes, bBytes); | ||
} | ||
|
||
export function bounce_if_not_authed(env, request) { | ||
if (!env.ADMIN_PASSWORD) { | ||
return new Response("Admin password is not configured.", { | ||
status: 403, | ||
}); | ||
} | ||
|
||
const authorization = request.headers.get("Authorization"); | ||
if (!authorization) { | ||
return new Response("You need to login.", { | ||
status: 401, | ||
headers: { | ||
// Prompts the user for credentials. | ||
"WWW-Authenticate": 'Basic realm="my scope", charset="UTF-8"', | ||
}, | ||
}); | ||
} | ||
const [scheme, encoded] = authorization.split(" "); | ||
|
||
// The Authorization header must start with Basic, followed by a space. | ||
if (!encoded || scheme !== "Basic") { | ||
return new Response("Malformed authorization header.", { | ||
status: 400, | ||
}); | ||
} | ||
|
||
const credentials = Buffer.from(encoded, "base64").toString(); | ||
|
||
// The username & password are split by the first colon. | ||
//=> example: "username:password" | ||
const index = credentials.indexOf(":"); | ||
const user = credentials.substring(0, index); | ||
const pass = credentials.substring(index + 1); | ||
|
||
if ( | ||
!timingSafeEqual("admin", user) || | ||
!timingSafeEqual(env.ADMIN_PASSWORD, pass) | ||
) { | ||
return new Response("You need to login.", { | ||
status: 401, | ||
headers: { | ||
// Prompts the user for credentials. | ||
"WWW-Authenticate": 'Basic realm="my scope", charset="UTF-8"', | ||
}, | ||
}); | ||
} | ||
|
||
// returning null means auth succeeded. | ||
return null; | ||
} |
Oops, something went wrong.