This commit is contained in:
parent
3365f4827e
commit
288dc4b085
@ -1,4 +1,15 @@
|
|||||||
export function downloadRecoveryCodes(codes, documentRef = document, urlApi = URL) {
|
export function buildRecoveryCodesFilename(username) {
|
||||||
|
const normalizedUsername = String(username || '')
|
||||||
|
.trim()
|
||||||
|
.replace(/[<>:"/\\|?*\u0000-\u001F]/g, '-')
|
||||||
|
.replace(/^[. -]+/g, '')
|
||||||
|
.replace(/-{2,}/g, '-')
|
||||||
|
.replace(/[. ]+$/g, '')
|
||||||
|
|
||||||
|
return `smail-${normalizedUsername || 'recovery-codes'}.txt`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function downloadRecoveryCodes(codes, username, documentRef = document, urlApi = URL) {
|
||||||
if (!Array.isArray(codes) || codes.length === 0) return false
|
if (!Array.isArray(codes) || codes.length === 0) return false
|
||||||
|
|
||||||
const blob = new Blob([`${codes.join('\n')}\n`], {
|
const blob = new Blob([`${codes.join('\n')}\n`], {
|
||||||
@ -8,7 +19,7 @@ export function downloadRecoveryCodes(codes, documentRef = document, urlApi = UR
|
|||||||
const anchor = documentRef.createElement('a')
|
const anchor = documentRef.createElement('a')
|
||||||
|
|
||||||
anchor.href = objectUrl
|
anchor.href = objectUrl
|
||||||
anchor.download = 'smail-recovery-codes.txt'
|
anchor.download = buildRecoveryCodesFilename(username)
|
||||||
anchor.style.display = 'none'
|
anchor.style.display = 'none'
|
||||||
documentRef.body.appendChild(anchor)
|
documentRef.body.appendChild(anchor)
|
||||||
|
|
||||||
|
|||||||
@ -300,7 +300,7 @@ export function usePage() {
|
|||||||
|
|
||||||
const saveRecoveryCodes = () => {
|
const saveRecoveryCodes = () => {
|
||||||
if (!generatedCodes.value.length) return
|
if (!generatedCodes.value.length) return
|
||||||
downloadRecoveryCodes(generatedCodes.value)
|
downloadRecoveryCodes(generatedCodes.value, globalStatus.userInfos.account)
|
||||||
notify('安全码已保存到本地文件,文件不会上传服务器', 'success')
|
notify('安全码已保存到本地文件,文件不会上传服务器', 'success')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import assert from 'node:assert/strict'
|
import assert from 'node:assert/strict'
|
||||||
import test from 'node:test'
|
import test from 'node:test'
|
||||||
import { readFileSync } from 'node:fs'
|
import { readFileSync } from 'node:fs'
|
||||||
import { downloadRecoveryCodes } from '../../frontend/src/utils/recoveryCodeDownload.js'
|
import { buildRecoveryCodesFilename, downloadRecoveryCodes } from '../../frontend/src/utils/recoveryCodeDownload.js'
|
||||||
import { RECOVERY_CODE_DISPLAY_MS } from '../../frontend/src/utils/recoveryCodeDisplay.js'
|
import { RECOVERY_CODE_DISPLAY_MS } from '../../frontend/src/utils/recoveryCodeDisplay.js'
|
||||||
|
|
||||||
const securitySettingsSource = readFileSync(new URL('../../frontend/src/views/components/SecuritySettings/SecuritySettings.js', import.meta.url), 'utf8')
|
const securitySettingsSource = readFileSync(new URL('../../frontend/src/views/components/SecuritySettings/SecuritySettings.js', import.meta.url), 'utf8')
|
||||||
@ -50,7 +50,7 @@ test('没有安全码时不生成下载文件', () => {
|
|||||||
revokeObjectURL() {},
|
revokeObjectURL() {},
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.equal(downloadRecoveryCodes([], fixture.documentRef, urlApi), false)
|
assert.equal(downloadRecoveryCodes([], 'xuans', fixture.documentRef, urlApi), false)
|
||||||
assert.equal(created, 0)
|
assert.equal(created, 0)
|
||||||
assert.equal(fixture.anchors.length, 0)
|
assert.equal(fixture.anchors.length, 0)
|
||||||
})
|
})
|
||||||
@ -70,14 +70,21 @@ test('安全码只在浏览器本地生成下载,不产生后端请求', async
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
downloadRecoveryCodes(['ABCD-1234', 'EFGH-5678'], fixture.documentRef, urlApi),
|
downloadRecoveryCodes(['ABCD-1234', 'EFGH-5678'], 'xuans', fixture.documentRef, urlApi),
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
assert.equal(fixture.anchors.length, 1)
|
assert.equal(fixture.anchors.length, 1)
|
||||||
assert.equal(fixture.anchors[0].href, 'blob:recovery-codes')
|
assert.equal(fixture.anchors[0].href, 'blob:recovery-codes')
|
||||||
assert.equal(fixture.anchors[0].download, 'smail-recovery-codes.txt')
|
assert.equal(fixture.anchors[0].download, 'smail-xuans.txt')
|
||||||
assert.equal(fixture.anchors[0].clicked, true)
|
assert.equal(fixture.anchors[0].clicked, true)
|
||||||
assert.equal(fixture.anchors[0].removed, true)
|
assert.equal(fixture.anchors[0].removed, true)
|
||||||
assert.deepEqual(revoked, ['blob:recovery-codes'])
|
assert.deepEqual(revoked, ['blob:recovery-codes'])
|
||||||
assert.equal(await blobs[0].text(), 'ABCD-1234\nEFGH-5678\n')
|
assert.equal(await blobs[0].text(), 'ABCD-1234\nEFGH-5678\n')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('导出文件名使用用户名并清理非法路径字符', () => {
|
||||||
|
assert.equal(buildRecoveryCodesFilename('xuans'), 'smail-xuans.txt')
|
||||||
|
assert.equal(buildRecoveryCodesFilename('user@example.com'), 'smail-user@example.com.txt')
|
||||||
|
assert.equal(buildRecoveryCodesFilename('../xuans/secret'), 'smail-xuans-secret.txt')
|
||||||
|
assert.equal(buildRecoveryCodesFilename(''), 'smail-recovery-codes.txt')
|
||||||
|
})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user