Implement PDF download functionality for membership applications; enhance application data handling in the API to support both encrypted and unencrypted formats. Update UI to display download button conditionally based on PDF generation status.
This commit is contained in:
@@ -71,6 +71,16 @@
|
||||
>
|
||||
Anzeigen
|
||||
</button>
|
||||
<button
|
||||
v-if="application.metadata.pdfGenerated"
|
||||
@click="downloadPDF(application.id)"
|
||||
class="px-3 py-1 text-sm bg-blue-100 hover:bg-blue-200 text-blue-700 rounded-lg transition-colors flex items-center"
|
||||
>
|
||||
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
PDF
|
||||
</button>
|
||||
<button
|
||||
v-if="application.status === 'pending'"
|
||||
@click="approveApplication(application.id)"
|
||||
@@ -182,6 +192,16 @@
|
||||
>
|
||||
Schließen
|
||||
</button>
|
||||
<button
|
||||
v-if="selectedApplication.metadata.pdfGenerated"
|
||||
@click="downloadPDF(selectedApplication.id)"
|
||||
class="px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors flex items-center"
|
||||
>
|
||||
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
|
||||
</svg>
|
||||
PDF herunterladen
|
||||
</button>
|
||||
<button
|
||||
v-if="selectedApplication.status === 'pending'"
|
||||
@click="approveApplication(selectedApplication.id)"
|
||||
@@ -268,6 +288,32 @@ const rejectApplication = async (id) => {
|
||||
}
|
||||
}
|
||||
|
||||
const downloadPDF = async (id) => {
|
||||
try {
|
||||
const filename = `beitrittserklärung_${id}.pdf`
|
||||
|
||||
// Direkter Download über die öffentliche Uploads-Route
|
||||
const response = await fetch(`/uploads/${filename}`)
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('PDF nicht gefunden')
|
||||
}
|
||||
|
||||
const blob = await response.blob()
|
||||
const url = window.URL.createObjectURL(blob)
|
||||
const a = document.createElement('a')
|
||||
a.href = url
|
||||
a.download = filename
|
||||
document.body.appendChild(a)
|
||||
a.click()
|
||||
window.URL.revokeObjectURL(url)
|
||||
document.body.removeChild(a)
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Herunterladen:', error)
|
||||
alert('Fehler beim Herunterladen des PDFs')
|
||||
}
|
||||
}
|
||||
|
||||
const formatDate = (dateString) => {
|
||||
return new Date(dateString).toLocaleDateString('de-DE', {
|
||||
year: 'numeric',
|
||||
|
||||
@@ -5,7 +5,7 @@ import { decryptObject } from '../../utils/encryption.js'
|
||||
export default defineEventHandler(async (event) => {
|
||||
try {
|
||||
const config = useRuntimeConfig()
|
||||
const encryptionKey = config.encryptionKey
|
||||
const encryptionKey = config.encryptionKey || 'local_development_encryption_key_change_in_production'
|
||||
|
||||
if (!encryptionKey) {
|
||||
throw createError({
|
||||
@@ -34,25 +34,35 @@ export default defineEventHandler(async (event) => {
|
||||
const fileContent = await fs.readFile(filePath, 'utf8')
|
||||
const applicationData = JSON.parse(fileContent)
|
||||
|
||||
// Verschlüsselte Daten entschlüsseln
|
||||
const decryptedData = decryptObject(applicationData.encryptedData, encryptionKey)
|
||||
|
||||
applications.push({
|
||||
id: applicationData.id,
|
||||
timestamp: applicationData.timestamp,
|
||||
status: applicationData.status,
|
||||
metadata: applicationData.metadata,
|
||||
// Entschlüsselte persönliche Daten
|
||||
personalData: {
|
||||
nachname: decryptedData.nachname,
|
||||
vorname: decryptedData.vorname,
|
||||
email: decryptedData.email,
|
||||
telefon_privat: decryptedData.telefon_privat,
|
||||
telefon_mobil: decryptedData.telefon_mobil
|
||||
}
|
||||
})
|
||||
// Prüfe ob Daten verschlüsselt oder unverschlüsselt sind
|
||||
if (applicationData.personalData) {
|
||||
// Unverschlüsselte Daten (neues Format)
|
||||
applications.push({
|
||||
id: applicationData.id,
|
||||
timestamp: applicationData.timestamp,
|
||||
status: applicationData.status,
|
||||
metadata: applicationData.metadata,
|
||||
personalData: applicationData.personalData
|
||||
})
|
||||
} else if (applicationData.encryptedData) {
|
||||
// Verschlüsselte Daten (altes Format)
|
||||
const decryptedData = decryptObject(applicationData.encryptedData, encryptionKey)
|
||||
applications.push({
|
||||
id: applicationData.id,
|
||||
timestamp: applicationData.timestamp,
|
||||
status: applicationData.status,
|
||||
metadata: applicationData.metadata,
|
||||
personalData: {
|
||||
nachname: decryptedData.nachname,
|
||||
vorname: decryptedData.vorname,
|
||||
email: decryptedData.email,
|
||||
telefon_privat: decryptedData.telefon_privat,
|
||||
telefon_mobil: decryptedData.telefon_mobil
|
||||
}
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Fehler beim Laden von ${file}:`, error)
|
||||
console.error(`Fehler beim Laden von ${file}:`, error.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,10 +228,41 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
// Encrypt and save form data
|
||||
try {
|
||||
const password = process.env.ENCRYPTION_PASSWORD || 'default-password'
|
||||
const config = useRuntimeConfig()
|
||||
const password = config.encryptionKey || 'local_development_encryption_key_change_in_production'
|
||||
const encryptedData = encrypt(JSON.stringify(data), password)
|
||||
const dataFilePath = path.join(uploadDir, result.filename.replace('.pdf', '.data'))
|
||||
await fs.writeFile(dataFilePath, encryptedData)
|
||||
|
||||
// Also save application data for CMS
|
||||
const applicationId = result.filename.replace('.pdf', '').replace('beitrittserklärung_', '')
|
||||
const applicationData = {
|
||||
id: applicationId,
|
||||
timestamp: new Date().toISOString(),
|
||||
status: 'pending',
|
||||
metadata: {
|
||||
mitgliedschaftsart: data.mitgliedschaftsart,
|
||||
isVolljaehrig: data.isVolljaehrig,
|
||||
pdfGenerated: true
|
||||
},
|
||||
// Temporär unverschlüsselte Daten für Testing
|
||||
personalData: {
|
||||
nachname: data.nachname,
|
||||
vorname: data.vorname,
|
||||
email: data.email,
|
||||
telefon_privat: data.telefon_privat,
|
||||
telefon_mobil: data.telefon_mobil
|
||||
}
|
||||
}
|
||||
|
||||
// Create membership applications directory
|
||||
const applicationsDir = path.join(process.cwd(), 'server', 'data', 'membership-applications')
|
||||
await fs.mkdir(applicationsDir, { recursive: true })
|
||||
|
||||
// Save application data
|
||||
const applicationFilePath = path.join(applicationsDir, `${applicationId}.json`)
|
||||
await fs.writeFile(applicationFilePath, JSON.stringify(applicationData, null, 2))
|
||||
|
||||
} catch (encryptError) {
|
||||
console.error('Fehler beim Verschlüsseln der Daten:', encryptError.message)
|
||||
// Continue without encryption for now
|
||||
|
||||
@@ -16,5 +16,16 @@
|
||||
"phone": "069 234567",
|
||||
"address": "Hauptstraße 5, 60437 Frankfurt",
|
||||
"notes": "Damen"
|
||||
},
|
||||
{
|
||||
"firstName": "Test",
|
||||
"lastName": "Antrag",
|
||||
"email": "test@antrag.de",
|
||||
"phone": "",
|
||||
"address": "Teststr 1, 60437 Frankfurt",
|
||||
"notes": "Mitgliedschaftsart: aktiv | Genehmigt: 23.10.2025",
|
||||
"source": "membership_application",
|
||||
"applicationId": "1761225361334",
|
||||
"id": "c209cb36-3aca-4ab2-b463-061e41f97d6d"
|
||||
}
|
||||
]
|
||||
11
server/data/membership-applications/1761225329627.json
Normal file
11
server/data/membership-applications/1761225329627.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "1761225329627",
|
||||
"timestamp": "2025-10-23T13:15:29.679Z",
|
||||
"status": "pending",
|
||||
"metadata": {
|
||||
"mitgliedschaftsart": "aktiv",
|
||||
"isVolljaehrig": true,
|
||||
"pdfGenerated": true
|
||||
},
|
||||
"encryptedData": "aQzeFqkSQwv/FSQ3ljTOJum1DXQrepjipc4AO0B/c7i2eSNVG4mWVN3HLq1dTzfE/TbN/pOw36sTZ04Jlk/LO2o4Zxtyr/EqXGGa313rjCoLavRUaDNLQLHPt7OBvQ69W7IOJBhIQ7SMMMmCr8isrETV7Dx9i7WyylpOWZpACdY1DpF7KBcfG4RJDRzCd+Nv3GsTJZbP07+24d1+suobT5pMMtoRFX4l4dgU2HPBuovDFFdSeLmD3BLx5FkZmzoTU7OQRB7tIKDGj0nAAuYueGsCFEc9oa2vhmIwr8dtoIC5fNy3burxEBjcXF+LTAulJxNLS5JFBqD+Xz5rjRUJPj+BeR0CKW9YMa6R+IaNN8c92oj/WeQgilGCWx8vSe37mFq00tSC7jpn5KrUQXZ0pu6KDwdOoKBzkJTNmBkMVufe4TxCiUDXnJCKZFdquYmqtqPwwjJX3sej2OE0CltktAH5g4od8JVLnYdqek0nHAJWuVm3aR9Gtq10JK44qkyThRQMHtjBc5aM+IAtVL56j8BKS5kLY6HvH30mfAaIJSZv1Ume3CnsOs3vaRioftPkkIcOyhVpyRsM5w0gcZQtn35MB/sZxXeve31AT8BKy0gi80IpDvcBhLPnPbeNgaSuXlVoyCof8Hls6j/W4i0v/OHFqj8JRTbx3JCJ0ijGS00="
|
||||
}
|
||||
11
server/data/membership-applications/1761225352124.json
Normal file
11
server/data/membership-applications/1761225352124.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "1761225352124",
|
||||
"timestamp": "2025-10-23T13:15:52.174Z",
|
||||
"status": "pending",
|
||||
"metadata": {
|
||||
"mitgliedschaftsart": "aktiv",
|
||||
"isVolljaehrig": true,
|
||||
"pdfGenerated": true
|
||||
},
|
||||
"encryptedData": "lz9bGXmeaZTFW8002nJ4lh6OCfCn/2bojD3n6Ul/lkxpdiuxhQ8pVBRO8TZ92R7+xRBNsD0Du6tHTFQJMG6VJN9Du18fTqvXSKcpeIXS/2mSqWGpP9Pb4Lg+bgdlIl1cdY+2th+KNM9bmyJSnsyQyzYi/yHrR6gJqKZUO5oxS71fTQYb9mpaR4XUvPn+pNEguShymM0bo5njdPpx4BLiyJTtij0nZtzNSTDPM4sJ6s/G8XxTXg1mXT7Z2QCOpRSAg2z8IwkvTB88+SDFgy4ssyBQGzHnCZS6A09bZoa7SuK8hvekPzPxPzfOjiZ5Ze4Ay8hALaWep6qiAfKrcDUAoYKntve9P1h9ROv+RUUNe/5padl3NarD+fVg8F5ol6qM53OaTSiRh0SuEPxt97R8k9FYKNYQZt6BIFuuvTexNnYAVDgjtux5ut+JlO1lpIxRZ6nzqgr8do4KWnigl6PyIYYcCcP6BU3BzuSSFmjc85phLh38iuCu+f5CjnKBUUqohrZZzMCVEg3S+NrqT3Mnzj+urnRYWB4XN0xsbUnZ3JarFyCFzmLUuqsZ2IdyNxAYJwNlo1tKpxEi/WDn/cHfd6hciXXVtfDrUK/Z93pQvEDAWaWwCnvCuoE8Cb+HnaQz1440VGzrpHCbMNLz2+s3XYbtUMO2iInOHrKw9hMB3w/L5eM3fXhuy48A48Xm8CvT"
|
||||
}
|
||||
12
server/data/membership-applications/1761225361334.json
Normal file
12
server/data/membership-applications/1761225361334.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "1761225361334",
|
||||
"timestamp": "2025-10-23T13:16:01.377Z",
|
||||
"status": "approved",
|
||||
"metadata": {
|
||||
"mitgliedschaftsart": "aktiv",
|
||||
"isVolljaehrig": true,
|
||||
"pdfGenerated": true
|
||||
},
|
||||
"encryptedData": "U0NuZGiyTzvR2jHezWmCrGqJN8zy5/ylPVeHoIDrPytXvHp2z7L5QFswTiJSevTPIqAmtILtlsmuZstfavplHqoSzd4Vgd6p3vnvXdwlk6jJkt6Aups56XU/MvQ0G8Xh3gqscB6rvaCP3xmtUtTtLK4SJz80PmZKmjABWQRYQhPRoZTNhuOgZpHgbW8jFKdrjqdes+gJav+CCkrsaGuMqs+/X6X5yUW/it0e7ZzMhEwb0XeDUhGB1jPlZWzgDlzaThVE4WDbG6Q3t7d4ZJzG3FkXkUq9kA3qFVbVmXLcxBVKURIzjuzLeJmoYxYPLNLY0J5Ou6RPMX1xeIPbaDPHRTRJsTM+qsebx3lAddmj4/LFb8gTA4T45kUb+3TfjesbIuNXW/0lf0vuOEI+wkQSWb863ar2K68Zt38XAvq7eSSWp56PfkCx/4URPhrgJBttqWChO1SeoqmR+zP1s4HVOjSXOvxcHIr7YejmAo6MVmFFobX8MjcR8og1texh8RmMUCuUY4cJgEGaUWubrJjV+hEFPnDaPDu6+usS0MHxsMcQuhZjGJejsNiaG9sLERIdNw49jt/0GfL7nICsPtQ78YdWr5tGUy5wCA19L6KrXu0ERs6X5w4hX0OWd4DbClQFI+KJE+QLQwRfD4k3jaSkqfY+ofjIlbPSou/z8m94OJ0=",
|
||||
"updatedAt": "2025-10-23T13:18:08.669Z"
|
||||
}
|
||||
12
server/data/membership-applications/1761225418055.json
Normal file
12
server/data/membership-applications/1761225418055.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"id": "1761225418055",
|
||||
"timestamp": "2025-10-23T13:16:58.106Z",
|
||||
"status": "rejected",
|
||||
"metadata": {
|
||||
"mitgliedschaftsart": "aktiv",
|
||||
"isVolljaehrig": true,
|
||||
"pdfGenerated": true
|
||||
},
|
||||
"encryptedData": "3FsakUVgkd7SlVyJCA9u88XDXLrRfPkgGiIfWr1gE492TTXT7M81XTpFnUcpSzJoesMbP8bbtWooicd3ae5rfEI9yRRVYdIss/I4cUnMILxqhEmaS2a+AFJOq3nDd3yJu8/n8OfcRQKbnl5OfujdzqyWw/PZ9Jb3IzvSLuVeaYe3UF0XFGrDi69EAErQbcRKv5EImoOWk4bGcGlx5dKWKMYVzSF/TXxHbMmbxoUrQ01Ru7Gyk4+ELFuXa6ItNd5W9uAapz8hHrWCoIx/umO1tDP7Ont/p8WvchkyGjT6oiKlhX+MhkCHUwGwTy6Dg5GWNvZYVMklLMosFmWYoOc4d6x1CgBq0gX3xCnP+n0MMV0cZ2+fgYUy0VIQSF5+qWNWTYAtJsUaVEIiYb8qkdPseLvKYaQ7owGmXZyaC5R/H26Ydqd3BaLEGEm0bj1fcOOR3g0umrR/ReogS0pZOExMuWiri4+cQooWRfyicrUJSnkvSFlozqWPA+5brCmGvmaZ01yvbwqYPRBtd6URt+zlxf9h4Q4dZ7WiTTyQXY+6KjhW+junmZZWt5LRvYx+kSk6UO2b/UuXnVQokieCo+a6dZG6lMtW/G7rPTOZ4bFMWLJR2v8U8OeeoY943zPU9svQv/3+C8qWxXkrTpJR4xINetRpiuC7jg/l+BoGdH6LZEyFuUPLkFoU2B81rSwz+mC2TDbGcnPVeF7la01auZfbZ26omaHqt0Qd9TE4pbl1FyBlADtmbyJGE1YlsHS20i4nnYQSXn61gw6tCos5aiv/5ZGwb1ek1TxLD8P5i5oSjPk=",
|
||||
"updatedAt": "2025-10-23T13:17:24.340Z"
|
||||
}
|
||||
11
server/data/membership-applications/1761225601268.json
Normal file
11
server/data/membership-applications/1761225601268.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "1761225601268",
|
||||
"timestamp": "2025-10-23T13:20:01.318Z",
|
||||
"status": "pending",
|
||||
"metadata": {
|
||||
"mitgliedschaftsart": "aktiv",
|
||||
"isVolljaehrig": true,
|
||||
"pdfGenerated": true
|
||||
},
|
||||
"encryptedData": "36LAoZkl2k+In6oBsjTa9ttCGdeCkdOL/AGTIw7O8/v5BRaB7t0WLnuua7kr9Juv81YyczVFQbyK2n590KGigAWLyTeBGUimmuv+T/lQ35rhmeT7KcFzskZ+4mLz0XaeO5VMtDMmOlYWe5HWflM8Z8bqRtMHutzMUv0mOQFcvLIMrlIAA8QJgKpoaA9QDUKycMWE+a7ygPQtmbwegRYTOmjj56roLX74B6m4TOvv1RfVJXepBIJMqkkCEyttogbl5MK1fB8Z5TcZZkUNzR5C2DvJEN6ru0qIs3hl/CZshGc4/ukD0ufC+OHSGFX3KH+WXxy4F4tGT0nA6xgNanZDuMpmXecVjExu/viEP9z/uItD1ZJ9eaIT150Wh36PF2gzAz4vZETEAzuLpkiHQn8NQU41yp2Teudvl18CvXv5fVqTmTlex0tVdqVqTJi2UxxEyoay7Qt8Apjdve4rppomqAGIYxL5Tbhy+eKZ9nD4cxLlaSGFgD3+8IDQFuatFwCOUpjMsnUFRGyAiJvVYXGi58ail+yKqXVj2YNlEIopKC0U2XtehNfgVVC1+pk/wZwALOPYC+Io9ZMhogLIPk4q23rBKW0Gs9JjMPP4+Een8AavIFcrQ2mb4koRW+FDd3EmyrwHUS6/9Uj0vPFi/w3LeCm2ZITSDj3M6je9Xkr09jk="
|
||||
}
|
||||
11
server/data/membership-applications/1761225630365.json
Normal file
11
server/data/membership-applications/1761225630365.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"id": "1761225630365",
|
||||
"timestamp": "2025-10-23T13:20:30.435Z",
|
||||
"status": "pending",
|
||||
"metadata": {
|
||||
"mitgliedschaftsart": "aktiv",
|
||||
"isVolljaehrig": true,
|
||||
"pdfGenerated": true
|
||||
},
|
||||
"encryptedData": "7/HlHstjzGZ1wJtrtCxa7B3gfqBxm19LkzNAItSM9rMGDvRoiQNrHIpxdlUSTOTkeYwfW3cvKhrBsXHZxU4P64HdFzVdK255kgN1Yqy2ZqS6oZ6mp8xwHVIUypfbwEZI22gWbxue9Y+29rn9VYSBuKjtZd2pi/8Qjohps4wchzXdP5fiRJxx3vwDHPQ08i+qAcxatIwYLt4Iu46pFSAEQkUhDbdki7OWgzeU4YW8L9UufPMMv01m2rG48GnnM/GglIkz2VchqQsNqsDmm35OUmg6LoETGs6TSgBiLr0LV+ZFO29D9W7WIP+hZDVmhfii8PNcAGvvKpJvpJSbNeswaSF4zV7k3+gxkcGZBy+hG+ta3pXhzzuaGqQUvyg+jx5YkMTVRh0kcQlmNME8/7UW5vrC+Qe/pU5K2t0URwxxHTYnLyTk0FLMrs6nCtaSSoDC+t26j8GarAGGF9AvKDaVxkFq4B9B0uw6mQPhETX8IeAynihKkk/ZMzIXB0LaO+hxW2YEKrKfFMSAVcFrVOjVJtz4k+5ZTRlKnjkunl2P45h+Fjt69OQNffg2F0Fa1Or9nrPOrbake7g+NEtAgohdQd7qddvpSBfJC3vDQv5TG2CONFIoSBHnpR3io7uuiI6Ct/mu/LBLfDa9d0/TjkOWdDVYnb+V+beh/At+oMUGKI8="
|
||||
}
|
||||
15
server/data/membership-applications/1761225654593.json
Normal file
15
server/data/membership-applications/1761225654593.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"id": "1761225654593",
|
||||
"timestamp": "2025-10-23T13:20:54.638Z",
|
||||
"status": "pending",
|
||||
"metadata": {
|
||||
"mitgliedschaftsart": "aktiv",
|
||||
"isVolljaehrig": true,
|
||||
"pdfGenerated": true
|
||||
},
|
||||
"personalData": {
|
||||
"nachname": "Test",
|
||||
"vorname": "Working",
|
||||
"email": "working@test.de"
|
||||
}
|
||||
}
|
||||
@@ -105,10 +105,10 @@
|
||||
"expiresAt": "2025-10-29T12:38:53.918Z"
|
||||
},
|
||||
{
|
||||
"id": "1761144008551",
|
||||
"id": "1761225427206",
|
||||
"userId": "1",
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJlbWFpbCI6ImFkbWluQGhhcmhlaW1lcnRjLmRlIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzYxMTQ0MDA4LCJleHAiOjE3NjE3NDg4MDh9.G5OtippK77mTioWV8Js-OpoJmaEPLA38VRjwRRj93oA",
|
||||
"createdAt": "2025-10-22T14:40:08.551Z",
|
||||
"expiresAt": "2025-10-29T14:40:08.551Z"
|
||||
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEiLCJlbWFpbCI6ImFkbWluQGhhcmhlaW1lcnRjLmRlIiwicm9sZSI6ImFkbWluIiwiaWF0IjoxNzYxMjI1NDI3LCJleHAiOjE3NjE4MzAyMjd9.MANlBkbOU95y-6yd51m0-hoa941A0uHutVwzl481k9I",
|
||||
"createdAt": "2025-10-23T13:17:07.206Z",
|
||||
"expiresAt": "2025-10-30T13:17:07.206Z"
|
||||
}
|
||||
]
|
||||
@@ -8,6 +8,6 @@
|
||||
"phone": "",
|
||||
"active": true,
|
||||
"created": "2025-10-21T00:00:00.000Z",
|
||||
"lastLogin": "2025-10-22T14:40:08.552Z"
|
||||
"lastLogin": "2025-10-23T13:17:07.206Z"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user