Skip to content

Commit

Permalink
Fix expiration parsing, support 'Y' and empty expiration (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
rutvora authored Aug 20, 2024
1 parent efc882e commit b6e0f6e
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 14 deletions.
7 changes: 5 additions & 2 deletions frontend/index.client.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ window.addEventListener('DOMContentLoaded', () => {
let customName = '', adminUrl = '', file = null

const NAME_REGEX = /^[a-zA-Z0-9+_\-\[\]*$@,;]{3,}$/
const EXPIRE_REGEX = /^\d+\s*[smhdwM]?$/
const EXPIRE_REGEX = /^\d+\s*[smhdwMY]?$/
const submitButton = $('#submit-button')
const deleteButton = $('#delete-button')
const pasteEditArea = $('#paste-textarea')
Expand All @@ -83,7 +83,10 @@ window.addEventListener('DOMContentLoaded', () => {
const pasteNotEmpty = inputType === 'edit'
? pasteEditArea.prop('value').length > 0
: file !== null
const expirationValid = EXPIRE_REGEX.test(expiration) // TODO: verify it
let expirationValid = EXPIRE_REGEX.test(expiration) // TODO: verify it
if (!expiration) {
expirationValid = true
}
const nameValid = urlType !== 'custom' || NAME_REGEX.test(customName)
const adminUrlValid = urlType !== 'admin' || isAdminUrlLegal(adminUrl)

Expand Down
2 changes: 1 addition & 1 deletion frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ <h2>Settings</h2>
<div id='paste-expiration-panel' class='paste-setting-subitem-panel'>
<input list='expiration-choices' type='text' min='60' step='1' name='paste-expiration'
id='paste-expiration-input' placeholder='Expiration (secs)' value='7d'>
<label class='small-label' for='paste-expiration-input'>Delete your paste after a period of time. <br>Units: s (seconds), m (minutes), h (hours), d (days), M (months)</label>
<label class='small-label' for='paste-expiration-input'>Delete your paste after a period of time (leave blank for no expiry). <br>Units: s (seconds), m (minutes), h (hours), d (days), M (months), Y (years)</label>
</div>
<div id='paste-passwd-panel' class='paste-setting-subitem-panel'>
<input type='text' spellcheck='false' name='paste-expiration' id='paste-passwd-input' placeholder='Password'>
Expand Down
8 changes: 6 additions & 2 deletions src/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,10 @@ export function parsePath(pathname) {
}

export function parseExpiration(expirationStr) {
const EXPIRE_REGEX = /^[\d\.]+\s*[smhdwM]?$/
if (!expirationStr) {
return NaN
}
const EXPIRE_REGEX = /^[\d\.]+\s*[smhdwMY]?$/
if (!EXPIRE_REGEX.test(expirationStr)) {
throw new WorkerError(400, `‘${expirationStr}’ is not a valid expiration specification`)
}
Expand All @@ -86,7 +89,8 @@ export function parseExpiration(expirationStr) {
else if (lastChar === 'h') expirationSeconds *= 3600
else if (lastChar === 'd') expirationSeconds *= 3600 * 24
else if (lastChar === 'w') expirationSeconds *= 3600 * 24 * 7
else if (lastChar === 'M') expirationSeconds *= 3600 * 24 * 7 * 30
else if (lastChar === 'M') expirationSeconds *= 3600 * 24 * 30
else if (lastChar === 'Y') expirationSeconds *= 3600 * 24 * 365
return expirationSeconds
}

Expand Down
17 changes: 10 additions & 7 deletions src/handlers/handleWrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,21 @@ async function createPaste(env, content, isPrivate, expire, short, createDate, p
}
}

await env.PB.put(short, content, {
expirationTtl: expire,
let options = {
metadata: {
postedAt: createDate,
passwd: passwd,
filename: filename,
lastModified: now,
},
})
}

if (!isNaN(expire)) {
options.expirationTtl = expire
}

await env.PB.put(short, content, options)

let accessUrl = env.BASE_URL + "/" + short
const adminUrl = env.BASE_URL + "/" + short + params.SEP + passwd
return {
Expand Down Expand Up @@ -101,10 +107,7 @@ export async function handlePostOrPut(request, env, ctx, isPut) {
let expirationSeconds = undefined
if (expire !== undefined) {
expirationSeconds = parseExpiration(expire)
if (isNaN(expirationSeconds)) {
throw new WorkerError(400, `cannot parse expire ${expirationSeconds} as an number`)
}
if (expirationSeconds < 60) {
if (!isNaN(expirationSeconds) && expirationSeconds < 60) {
throw new WorkerError(
400,
`due to limitation of Cloudflare, expire should be a integer greater than 60, '${expirationSeconds}' given`,
Expand Down
6 changes: 4 additions & 2 deletions test/basic.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,10 @@ test("expire", async () => {
await testExpireParse("100m", 6000)
await testExpireParse("100h", 360000)
await testExpireParse("1d", 86400)
await testExpireParse("1M", 18144000)
await testExpireParse("1M", 2592000)
await testExpireParse("1Y", 31536000)
await testExpireParse("100 m", 6000)
await testExpireParse("", null)

const testFailParse = async (expire) => {
const uploadResponse = await workerFetch(new Request(BASE_URL, {
Expand Down Expand Up @@ -205,4 +207,4 @@ test("custom passwd", async () => {
expect(putResponseJson["admin"]).toStrictEqual(`${url}:${wrongPasswd}`) // passwd may change
})

// TODO: add tests for CORS
// TODO: add tests for CORS

0 comments on commit b6e0f6e

Please sign in to comment.