Skip to content

Commit

Permalink
fix[frontend]: unify handling of expiration
Browse files Browse the repository at this point in the history
  • Loading branch information
SharzyL committed Mar 10, 2024
1 parent 4bff359 commit 7c14e8a
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 33 deletions.
55 changes: 26 additions & 29 deletions frontend/index.client.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ function parsePath(pathname) {
return { role, short, passwd, ext }
}

window.addEventListener('load', () => {
window.addEventListener('DOMContentLoaded', () => {
const base_url = '{{BASE_URL}}'
const deploy_date = new Date('{{DEPLOY_DATE}}')

Expand All @@ -34,17 +34,6 @@ window.addEventListener('load', () => {

$('#deploy-date').text(getDateString(deploy_date))

function copyTextFromInput(input) {
if (input.constructor === String) input = document.getElementById(input)
input.focus()
input.select()
try {
document.execCommand('copy')
} catch (err) {
alert('Failed to copy content')
}
}

function isAdminUrlLegal(url) {
try {
url = new URL(url)
Expand All @@ -71,35 +60,44 @@ window.addEventListener('load', () => {
}
}

// monitor input changes and enable/disable submit button
let urlType = 'short', inputType = 'edit', expiration = '', passwd = ''
// monitor input changes and enable/disable submit button
let urlType = $('input[name="url-type"]:checked').val()
let inputType = 'edit'
let expiration = $('#paste-expiration-input').val()
let passwd = ''
let customName = '', adminUrl = '', file = null

const NAME_REGEX = /^[a-zA-Z0-9+_\-\[\]*$=@,;/]{3,}$/
const NAME_REGEX = /^[a-zA-Z0-9+_\-\[\]*$@,;\/]{3,}$/
const EXPIRE_REGEX = /^\d+\s*[mhdwM]?$/
const submitButton = $('#submit-button')
const deleteButton = $('#delete-button')
const pasteEditArea = $('#paste-textarea')
const submitErrMsg = $('#submit-error-msg')

function disableSubmitButton(reason) {
submitButton.removeClass('enabled')
submitErrMsg.text(reason)
}

function updateButtons() {
const pasteNotEmpty = inputType === 'edit'
? pasteEditArea.prop('value').length > 0
: file !== null
const expirationValid = true // TODO: verify it
const expirationValid = EXPIRE_REGEX.test(expiration) // TODO: verify it
const nameValid = urlType !== 'custom' || NAME_REGEX.test(customName)
const adminUrlValid = urlType !== 'admin' || isAdminUrlLegal(adminUrl)

if (pasteNotEmpty && expirationValid && nameValid && adminUrlValid) {
submitButton.addClass('enabled')
submitButton.prop('title', '')
if (!pasteNotEmpty) {
disableSubmitButton('Paste is empty')
} else if (!expirationValid) {
disableSubmitButton(`Expiration “${expiration}” not valid`)
} else if (!nameValid) {
disableSubmitButton(`The customized URL should satisfy regex ${NAME_REGEX}`)
} else if (!adminUrlValid) {
disableSubmitButton(`Admin URL “${adminUrl}” not valid`)
} else {
submitButton.removeClass('enabled')
if (!pasteNotEmpty) {
submitButton.prop('title', 'Cannot upload empty paste')
} else if (!expirationValid) {
submitButton.prop('title', 'Expiration should be more than 60 seconds')
} else if (!nameValid) {
submitButton.prop('title', `The customized URL should satisfy regex ${NAME_REGEX}`)
}
submitButton.addClass('enabled')
submitErrMsg.text('')
}

if (urlType === 'admin') {
Expand All @@ -115,8 +113,7 @@ window.addEventListener('load', () => {
submitButton.prop('title', '')
} else {
deleteButton.removeClass('enabled')
submitButton.prop('title', `The admin URL should start with ${base_url} and contain a colon`)
deleteButton.prop('title', `The admin URL should start with ${base_url} and contain a colon`)
submitErrMsg.text(`The admin URL should start with “${base_url}” and contain a colon`)
}
}

Expand Down
7 changes: 5 additions & 2 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,11 @@ <h2>Uploaded paste</h2>
</div>
<label for='uploaded-expiration' class='small-label'>Expiration</label>
</div>
<button id='submit-button' class='long-button px-3 py-2 my-1'>Upload</button>
<button id='delete-button' class='long-button hidden px-3 py-2 my-1'>Delete</button>
<div>
<button id='submit-button' class='long-button px-3 py-2 my-1'>Upload</button>
<button id='delete-button' class='long-button hidden px-3 py-2 my-1'>Delete</button>
<span id='submit-error-msg'></span>
</div>
</div>
<footer class='px-3 my-2 text-center'>
<p>
Expand Down
8 changes: 8 additions & 0 deletions frontend/style.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion src/common.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const params = {
CHAR_GEN : "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678",
NAME_REGEX : /^[a-zA-Z0-9+_\-\[\]*$:@,;\/]{3,}$/,
NAME_REGEX : /^[a-zA-Z0-9+_\-\[\]*$@,;\/]{3,}$/,
RAND_LEN : 4,
PRIVATE_RAND_LEN : 24,
ADMIN_PATH_LEN : 24,
Expand Down Expand Up @@ -75,6 +75,11 @@ export function parsePath(pathname) {
}

export function parseExpiration(expirationStr) {
const EXPIRE_REGEX = /^[\d\.]+\s*[mhdwM]?$/
if (!EXPIRE_REGEX.test(expirationStr)) {
throw new WorkerError(400, `‘${expirationStr}’ is not a valid expiration specification`)
}

let expirationSeconds = parseFloat(expirationStr)
const lastChar = expirationStr[expirationStr.length - 1]
if (lastChar === 'm') expirationSeconds *= 60
Expand Down
23 changes: 22 additions & 1 deletion test/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,27 @@ _test_long_mode() {
it 'should return the original paste' [ "$(cat "$tmp_file")" = "$test_text" ]
}

_test_expire() {
test_text="hello world"
start_test "uploading paste"

it 'should accept ‘100m’ expiration' curl_code 200 -o "$tmp_file" -Fc="$test_text" -Fe=100m "$localaddr"
expire=$(jq -r '.expire' "$tmp_file")
it 'should return a correct expire' [ "$expire" = 6000 ]

it 'should accept ‘1000’ expiration' curl_code 200 -o "$tmp_file" -Fc="$test_text" -Fe=1000 "$localaddr"
expire=$(jq -r '.expire' "$tmp_file")
it 'should return a correct expire' [ "$expire" = 1000 ]

it 'should accept ‘100 m’ expiration' curl_code 200 -o "$tmp_file" -Fc="$test_text" -Fe="100 m" "$localaddr"
expire=$(jq -r '.expire' "$tmp_file")
it 'should return a correct expire' [ "$expire" = 6000 ]

it 'should reject illegal expiration' curl_code 400 -o "$tmp_file" -Fc="$test_text" -Fe=abc "$localaddr"
it 'should reject illegal expiration' curl_code 400 -o "$tmp_file" -Fc="$test_text" -Fe=1c "$localaddr"
it 'should reject illegal expiration' curl_code 400 -o "$tmp_file" -Fc="$test_text" -Fe=-100m "$localaddr"
}

_test_markdown() {
test_text="#Hello"
start_test "uploading paste"
Expand Down Expand Up @@ -291,7 +312,7 @@ pgrep -f workerd > /dev/null || die "no workerd is running, please start one ins
if [ $# -gt 0 ]; then
test_chapters "$@"
else
test_chapters primary long_mode custom_path \
test_chapters primary expire long_mode custom_path \
markdown url_redirect content_disposition \
mime highlight custom_passwd suggest
fi
Expand Down

0 comments on commit 7c14e8a

Please sign in to comment.