fix: security hardening + code quality improvements (401 retry limit, UUID crypto, debounce this-bug, deduplicate CSS/helpers, optimize SW precache)
This commit is contained in:
@@ -27,11 +27,13 @@ class AuthService {
|
||||
return crypto.randomUUID()
|
||||
}
|
||||
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
const r = Math.random() * 16 | 0
|
||||
const v = c === 'x' ? r : (r & 0x3 | 0x8)
|
||||
return v.toString(16)
|
||||
})
|
||||
const bytes = new Uint8Array(16)
|
||||
crypto.getRandomValues(bytes)
|
||||
bytes[6] = (bytes[6] & 0x0f) | 0x40
|
||||
bytes[8] = (bytes[8] & 0x3f) | 0x80
|
||||
return [...bytes].map((b, i) =>
|
||||
([4, 6, 8, 10].includes(i) ? '-' : '') + b.toString(16).padStart(2, '0')
|
||||
).join('')
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,14 +18,13 @@ class ConversationsService {
|
||||
return this.hashPublicKey(publicKey)
|
||||
}
|
||||
|
||||
hashPublicKey(publicKey) {
|
||||
async hashPublicKey(publicKey) {
|
||||
const encoder = new TextEncoder()
|
||||
const data = encoder.encode(publicKey)
|
||||
return crypto.subtle.digest('SHA-256', data).then(hash => {
|
||||
return Array.from(new Uint8Array(hash))
|
||||
.map(b => b.toString(16).padStart(2, '0'))
|
||||
.join('')
|
||||
})
|
||||
const hash = await crypto.subtle.digest('SHA-256', data)
|
||||
return Array.from(new Uint8Array(hash))
|
||||
.map(b => b.toString(16).padStart(2, '0'))
|
||||
.join('')
|
||||
}
|
||||
|
||||
async getMyConversations() {
|
||||
|
||||
@@ -45,6 +45,7 @@ class DirectusService {
|
||||
this.refreshToken = null
|
||||
this.tokenExpiry = null
|
||||
this.refreshTimeout = null
|
||||
this._refreshPromise = null
|
||||
|
||||
this.loadTokens()
|
||||
this.setupVisibilityRefresh()
|
||||
@@ -153,15 +154,17 @@ class DirectusService {
|
||||
headers
|
||||
})
|
||||
|
||||
// Token expired - try refresh (but not for auth endpoints)
|
||||
if (response.status === 401 && this.refreshToken && !endpoint.startsWith('/auth/')) {
|
||||
const refreshed = await this.refreshSession()
|
||||
if (refreshed) {
|
||||
return this.request(endpoint, options)
|
||||
} else {
|
||||
this.clearTokens()
|
||||
return this.request(endpoint, options)
|
||||
if (response.status === 401 && this.refreshToken && !endpoint.startsWith('/auth/') && _retryCount < 1) {
|
||||
if (!this._refreshPromise) {
|
||||
this._refreshPromise = this.refreshSession().finally(() => {
|
||||
this._refreshPromise = null
|
||||
})
|
||||
}
|
||||
const refreshed = await this._refreshPromise
|
||||
if (!refreshed) {
|
||||
this.clearTokens()
|
||||
}
|
||||
return this.request(endpoint, options, _retryCount + 1)
|
||||
}
|
||||
|
||||
if (response.status === 429 && _retryCount < 3) {
|
||||
|
||||
Reference in New Issue
Block a user