Skip to content

Commit

Permalink
Fix user state issues with signUp breaking follows (#10419)
Browse files Browse the repository at this point in the history
  • Loading branch information
schottra authored Nov 11, 2024
1 parent e04b249 commit e7c6a80
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 47 deletions.
10 changes: 9 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/libs/src/NativeAudiusLibs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ export class AudiusLibs {
await this.determineCreatorNodeEndpointForWallet(wallet)
)
this.discoveryProvider?.setCurrentUser(userId)
this.EntityManager?.setCurrentUserId(userId)
}

getCurrentUser() {
Expand All @@ -446,6 +447,7 @@ export class AudiusLibs {
delete this.currentUserId
this.creatorNode?.setEndpoint(this.creatorNodeConfig.fallbackUrl)
this.discoveryProvider?.clearCurrentUser()
this.EntityManager?.clearCurrentUserId()
}

/** Init services based on presence of a relevant config. */
Expand Down
2 changes: 2 additions & 0 deletions packages/libs/src/WebAudiusLibs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ export class AudiusLibs {
await this.determineCreatorNodeEndpointForWallet(wallet)
)
this.discoveryProvider?.setCurrentUser(userId)
this.EntityManager?.setCurrentUserId(userId)
}

getCurrentUser() {
Expand All @@ -470,6 +471,7 @@ export class AudiusLibs {
delete this.currentUserId
this.creatorNode?.setEndpoint(this.creatorNodeConfig.fallbackUrl)
this.discoveryProvider?.clearCurrentUser()
this.EntityManager?.clearCurrentUserId()
}

/** Init services based on presence of a relevant config. */
Expand Down
1 change: 1 addition & 0 deletions packages/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"abi-decoder": "2.4.0",
"ajv": "6.12.2",
"assert": "2.0.0",
"async-mutex": "0.5.0",
"async-retry": "1.3.1",
"axios": "0.19.2",
"bn.js": "5.2.1",
Expand Down
87 changes: 41 additions & 46 deletions packages/sdk/src/sdk/middleware/addRequestSignatureMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Mutex } from 'async-mutex'

import {
type Middleware,
type RequestContext,
Expand All @@ -19,65 +21,58 @@ export const addRequestSignatureMiddleware = ({
}: {
services: Pick<ServicesContainer, 'auth' | 'logger'>
}): Middleware => {
const mutex = new Mutex()
let message: string | null = null
let signatureAddress: string | null = null
let signature: string | null = null
let timestamp: number | null = null

let signaturePromise: Promise<void> | null = null

return {
pre: async (context: RequestContext): Promise<FetchParams> => {
const getSignature = async () => {
// Run this exclusively to prevent multiple requests from updating the signature at the same time
// and reverting to an older signature
return mutex.runExclusive(async () => {
const { auth, logger } = services
const currentAddress = await auth.getAddress()
const currentTimestamp = new Date().getTime()
const isExpired =
!timestamp || timestamp + SIGNATURE_EXPIRY_MS < currentTimestamp

// Using a promise so that only one request at a time is allowed to
// update the signature.
// Any requests that queue behind the one updating will wait for the promise
// to resolve and then read the result.
if (!signaturePromise) {
signaturePromise = (async () => {
const currentAddress = await auth.getAddress()
const currentTimestamp = new Date().getTime()
const isExpired =
!timestamp || timestamp + SIGNATURE_EXPIRY_MS < currentTimestamp

const needsUpdate =
!message ||
!signature ||
isExpired ||
signatureAddress !== currentAddress
const needsUpdate =
!message ||
!signature ||
isExpired ||
signatureAddress !== currentAddress

if (needsUpdate) {
try {
signatureAddress = currentAddress
if (needsUpdate) {
try {
signatureAddress = currentAddress

const m = `signature:${currentTimestamp}`
const prefix = `\x19Ethereum Signed Message:\n${m.length}`
const prefixedMessage = prefix + m
const m = `signature:${currentTimestamp}`
const prefix = `\x19Ethereum Signed Message:\n${m.length}`
const prefixedMessage = prefix + m

const [sig, recid] = await auth.sign(
Buffer.from(prefixedMessage, 'utf-8')
)
const r = Buffer.from(sig.slice(0, 32)).toString('hex')
const s = Buffer.from(sig.slice(32, 64)).toString('hex')
const v = (recid + 27).toString(16)
const [sig, recid] = await auth.sign(
Buffer.from(prefixedMessage, 'utf-8')
)
const r = Buffer.from(sig.slice(0, 32)).toString('hex')
const s = Buffer.from(sig.slice(32, 64)).toString('hex')
const v = (recid + 27).toString(16)

// Cache the new signature and message
message = m
signature = `0x${r}${s}${v}`
timestamp = currentTimestamp
} catch (e) {
logger.warn(`Unable to add request signature: ${e}`)
} finally {
// Clear the promise after update is complete
signaturePromise = null
}
}
})()
// Cache the new signature and message
message = m
signature = `0x${r}${s}${v}`
timestamp = currentTimestamp
} catch (e) {
logger.warn(`Unable to add request signature: ${e}`)
}
}
return { message, signature }
})
}

// Wait for current check/update signature to complete
await signaturePromise
return {
pre: async (context: RequestContext): Promise<FetchParams> => {
const { message, signature } = await getSignature()

// Return the updated request with the signature in the headers
return !!message && !!signature
Expand Down

0 comments on commit e7c6a80

Please sign in to comment.