Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions gas/Code.gs
Original file line number Diff line number Diff line change
Expand Up @@ -501,10 +501,17 @@ function writeReport(reportData, clientId, recaptchaToken) {
if (!studentId || !/^[a-zA-Z][0-9]{7}$/.test(studentId)) {
return { success: false, error: 'VALIDATION_STUDENT_ID_FORMAT' };
}
if (!roomNumber || !/^[A-Za-z0-9-]{1,8}$/.test(roomNumber)) {
// ⚠️ 修正(BUG-ROOM-01):原本 /^[A-Za-z0-9-]{1,8}$/ 過於寬鬆,
// 允許純數字(如 "229")繞過前端驗證直接寫入試算表。
// 現改為與 report.js 前端驗證完全一致:
// 必須以 H、I、G、FA~FF 開頭,後接 1~4 位數字,可選一個連字號再接數字。
if (!roomNumber || !/^(H|I|G|F[ABCDEF])[0-9]{1,4}(-[0-9]+)?$/i.test(roomNumber)) {
return { success: false, error: 'VALIDATION_ROOM_FORMAT' };
}
if (!bedNumber || !/^[0-9]{1,3}$/.test(bedNumber)) {
// ⚠️ 修正(BUG-BED-01):原本 /^[0-9]{1,3}$/ 允許 1~3 位數字,
// 而前端 report.js 僅允許 1 位數字(/^[0-9]$/),造成前後端不一致。
// 改為與前端一致:僅允許單一位數字(0~9)。
if (!bedNumber || !/^[0-9]$/.test(bedNumber)) {
return { success: false, error: 'VALIDATION_BED_FORMAT' };
}
if (!phone || !/^[0-9]{10}$/.test(phone)) {
Expand Down
2 changes: 1 addition & 1 deletion test/gas-code.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ function validReportPayload() {
return {
studentId: 'D1234567',
name: '王小明',
roomNumber: 'A101',
roomNumber: 'H101', // 修正:A 開頭不合法,改為合法的 H 前綴(BUG-ROOM-01 對齊)
bedNumber: '2',
phone: '0912345678',
repairTime: '18:00–21:00',
Expand Down
11 changes: 7 additions & 4 deletions test/validation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ function validatePhone(phone) {

function validateBedNumber(bed) {
if (!bed || typeof bed !== 'string') return false;
return /^[0-9]{1,3}$/.test(bed.trim());
// 修正(BUG-BED-01):對齊後端 Code.gs 與前端 report.js,僅允許單一位數字
return /^[0-9]$/.test(bed.trim());
}

test('Student ID validation (1 letter + 7 digits)', () => {
Expand All @@ -35,10 +36,12 @@ test('Phone validation (10 digits)', () => {
assert.equal(validatePhone('abc0912345'), false, 'Letters in phone should fail');
});

test('Bed number validation (1-3 digits)', () => {
test('Bed number validation (1 digit only)', () => {
assert.equal(validateBedNumber('1'), true, '1 digit');
assert.equal(validateBedNumber('12'), true, '2 digits');
assert.equal(validateBedNumber('123'), true, '3 digits');
assert.equal(validateBedNumber('9'), true, 'single digit 9');
assert.equal(validateBedNumber('0'), true, 'single digit 0');
assert.equal(validateBedNumber('12'), false, '2 digits should fail (front+backend now consistent)');
assert.equal(validateBedNumber('123'), false, '3 digits should fail (front+backend now consistent)');
assert.equal(validateBedNumber('1234'), false, '4 digits should fail');
assert.equal(validateBedNumber('A'), false, 'Non-digits should fail');
});
Expand Down
Loading