@@ -1609,73 +1609,98 @@ export default {
1609
1609
1610
1610
async handleDeleteUser ( request , env ) {
1611
1611
try {
1612
- // This endpont requires admin API_SECRET
1612
+ // This endpoint requires admin API_SECRET
1613
1613
const authHeader = request . headers . get ( 'Authorization' ) ;
1614
1614
if ( ! authHeader || authHeader !== `Bearer ${ env . API_SECRET } ` ) {
1615
1615
return new Response ( JSON . stringify ( { error : 'Unauthorized' } ) , {
1616
1616
status : 401 ,
1617
1617
headers : { ...CORS_HEADERS , 'Content-Type' : 'application/json' }
1618
1618
} ) ;
1619
1619
}
1620
-
1621
- // Parse request once
1620
+
1622
1621
const data = await request . json ( ) ;
1623
1622
const { username } = data ;
1624
-
1623
+
1625
1624
if ( ! username ) {
1626
1625
return new Response ( JSON . stringify ( { error : 'Missing username' } ) , {
1627
1626
status : 400 ,
1628
1627
headers : { ...CORS_HEADERS , 'Content-Type' : 'application/json' }
1629
1628
} ) ;
1630
1629
}
1631
-
1632
- // First delete the user from UserAuthDO
1633
- const authId = env . USER_AUTH . idFromName ( "global" ) ;
1634
- const auth = env . USER_AUTH . get ( authId ) ;
1635
-
1636
- const authResponse = await auth . fetch ( new Request ( 'http://internal/delete-user' , {
1637
- method : 'POST' ,
1638
- headers : {
1639
- 'Content-Type' : 'application/json'
1640
- } ,
1641
- body : JSON . stringify ( { username } )
1642
- } ) ) ;
1643
-
1644
- if ( ! authResponse . ok ) {
1645
- throw new Error ( 'Failed to delete user authentication data' ) ;
1646
- }
1647
-
1648
- // Then delete all their author data and resources
1649
- const registryId = env . PLUGIN_REGISTRY . idFromName ( "global" ) ;
1650
- const registry = env . PLUGIN_REGISTRY . get ( registryId ) ;
1651
-
1652
- const registryResponse = await registry . fetch ( new Request ( 'http://internal/delete-author' , {
1653
- method : 'POST' ,
1654
- headers : {
1655
- 'Content-Type' : 'application/json'
1656
- } ,
1657
- body : JSON . stringify ( { authorName : username } )
1658
- } ) ) ;
1659
-
1660
- if ( ! registryResponse . ok ) {
1661
- throw new Error ( 'Failed to delete author data' ) ;
1662
- }
1663
-
1664
- // Delete all their files from bucket
1665
- const prefix = `${ username } /` ;
1666
- const files = await env . PLUGIN_BUCKET . list ( { prefix } ) ;
1667
- for ( const file of files . objects ) {
1668
- await env . PLUGIN_BUCKET . delete ( file . key ) ;
1669
- }
1670
-
1671
- return new Response ( JSON . stringify ( {
1630
+
1631
+ // Delete user data in parallel for better performance
1632
+ const [ authResult , registryResult , bucketResult ] = await Promise . allSettled ( [
1633
+ // 1. Delete from UserAuthDO
1634
+ ( async ( ) => {
1635
+ const authId = env . USER_AUTH . idFromName ( "global" ) ;
1636
+ const auth = env . USER_AUTH . get ( authId ) ;
1637
+ const response = await auth . fetch ( new Request ( 'http://internal/delete-user' , {
1638
+ method : 'POST' ,
1639
+ headers : { 'Content-Type' : 'application/json' } ,
1640
+ body : JSON . stringify ( { username } )
1641
+ } ) ) ;
1642
+
1643
+ if ( ! response . ok ) {
1644
+ const error = await response . text ( ) ;
1645
+ throw new Error ( `Auth deletion failed: ${ error } ` ) ;
1646
+ }
1647
+ return await response . json ( ) ;
1648
+ } ) ( ) ,
1649
+
1650
+ // 2. Delete from PluginRegistryDO
1651
+ ( async ( ) => {
1652
+ const registryId = env . PLUGIN_REGISTRY . idFromName ( "global" ) ;
1653
+ const registry = env . PLUGIN_REGISTRY . get ( registryId ) ;
1654
+ const response = await registry . fetch ( new Request ( 'http://internal/delete-author' , {
1655
+ method : 'POST' ,
1656
+ headers : { 'Content-Type' : 'application/json' } ,
1657
+ body : JSON . stringify ( { authorName : username } )
1658
+ } ) ) ;
1659
+
1660
+ if ( ! response . ok ) {
1661
+ const error = await response . text ( ) ;
1662
+ throw new Error ( `Registry deletion failed: ${ error } ` ) ;
1663
+ }
1664
+ return await response . json ( ) ;
1665
+ } ) ( ) ,
1666
+
1667
+ // 3. Delete files from bucket
1668
+ ( async ( ) => {
1669
+ const prefix = `${ username } /` ;
1670
+ const files = await env . PLUGIN_BUCKET . list ( { prefix } ) ;
1671
+ const deletionResults = await Promise . all (
1672
+ files . objects . map ( file => env . PLUGIN_BUCKET . delete ( file . key ) )
1673
+ ) ;
1674
+ return { deletedFiles : files . objects . length } ;
1675
+ } ) ( )
1676
+ ] ) ;
1677
+
1678
+ // Process results and build response
1679
+ const response = {
1672
1680
success : true ,
1673
- message : `User ${ username } and all associated data have been deleted`
1674
- } ) , {
1681
+ details : {
1682
+ auth : authResult . status === 'fulfilled' ? authResult . value : { error : authResult . reason ?. message } ,
1683
+ registry : registryResult . status === 'fulfilled' ? registryResult . value : { error : registryResult . reason ?. message } ,
1684
+ storage : bucketResult . status === 'fulfilled' ? bucketResult . value : { error : bucketResult . reason ?. message }
1685
+ }
1686
+ } ;
1687
+
1688
+ // If any operation failed, mark overall success as false but continue with others
1689
+ if ( authResult . status === 'rejected' || registryResult . status === 'rejected' || bucketResult . status === 'rejected' ) {
1690
+ response . success = false ;
1691
+ response . message = 'Some deletion operations failed. Check details for more information.' ;
1692
+ return new Response ( JSON . stringify ( response ) , {
1693
+ status : 207 , // 207 Multi-Status
1694
+ headers : { ...CORS_HEADERS , 'Content-Type' : 'application/json' }
1695
+ } ) ;
1696
+ }
1697
+
1698
+ response . message = `User ${ username } and all associated data have been deleted` ;
1699
+ return new Response ( JSON . stringify ( response ) , {
1675
1700
status : 200 ,
1676
1701
headers : { ...CORS_HEADERS , 'Content-Type' : 'application/json' }
1677
1702
} ) ;
1678
-
1703
+
1679
1704
} catch ( error ) {
1680
1705
console . error ( 'Error deleting user:' , error ) ;
1681
1706
return new Response ( JSON . stringify ( {
@@ -1688,7 +1713,7 @@ export default {
1688
1713
} ) ;
1689
1714
}
1690
1715
} ,
1691
-
1716
+
1692
1717
async fetch ( request , env ) {
1693
1718
const url = new URL ( request . url ) ;
1694
1719
const path = url . pathname ;
0 commit comments