diff --git a/src/@types/commands.ts b/src/@types/commands.ts index 723cb84c0..e07f77697 100644 --- a/src/@types/commands.ts +++ b/src/@types/commands.ts @@ -292,12 +292,6 @@ export interface CreateAuthTokenCommand extends Command { validUntil?: number | null } -export interface InvalidateAuthTokenCommand extends Command { - address: string - signature: string - token: string -} - export interface GetJobsCommand extends Command { environments?: string[] fromTimestamp?: string diff --git a/src/components/Auth/index.ts b/src/components/Auth/index.ts index 94e1ab0c4..879c52625 100644 --- a/src/components/Auth/index.ts +++ b/src/components/Auth/index.ts @@ -11,6 +11,7 @@ export interface AuthValidation { nonce?: string signature?: string message?: string + chainId?: string | null } export class Auth { @@ -42,9 +43,16 @@ export class Auth { address: string, jwtToken: string, validUntil: number, - createdAt: number + createdAt: number, + chainId?: string | null ): Promise { - await this.authTokenDatabase.createToken(jwtToken, address, validUntil, createdAt) + await this.authTokenDatabase.createToken( + jwtToken, + address, + validUntil, + createdAt, + chainId + ) } async invalidateToken(jwtToken: string): Promise { @@ -71,7 +79,7 @@ export class Auth { async validateAuthenticationOrToken( authValidation: AuthValidation ): Promise { - const { token, address, nonce, signature, message } = authValidation + const { token, address, nonce, signature, message, chainId } = authValidation try { if (signature && address && nonce) { const oceanNode = OceanNode.getInstance() @@ -80,7 +88,8 @@ export class Auth { address, parseInt(nonce), signature, - message + message, + chainId ) if (!nonceCheckResult.valid) { diff --git a/src/components/core/handler/authHandler.ts b/src/components/core/handler/authHandler.ts index 8e960c14f..fbe5c45d2 100644 --- a/src/components/core/handler/authHandler.ts +++ b/src/components/core/handler/authHandler.ts @@ -17,10 +17,12 @@ export interface AuthMessage { export interface CreateAuthTokenCommand extends AuthMessage, Command { validUntil?: number | null + chainId?: string | null } export interface InvalidateAuthTokenCommand extends AuthMessage, Command { token: string + chainId?: string | null } export class CreateAuthTokenHandler extends CommandHandler { @@ -42,7 +44,8 @@ export class CreateAuthTokenHandler extends CommandHandler { address, parseInt(nonce), signature, - String(address + nonce) + String(address + nonce), + task.chainId ) if (!nonceCheckResult.valid) { @@ -59,7 +62,7 @@ export class CreateAuthTokenHandler extends CommandHandler { await this.getOceanNode() .getAuth() - .insertToken(task.address, jwtToken, task.validUntil, createdAt) + .insertToken(task.address, jwtToken, task.validUntil, createdAt, task.chainId) return { stream: Readable.from(JSON.stringify({ token: jwtToken })), @@ -93,7 +96,8 @@ export class InvalidateAuthTokenHandler extends CommandHandler { address, parseInt(nonce), signature, - String(address + nonce) + String(address + nonce), + task.chainId ) if (!isValid) { return { diff --git a/src/components/core/utils/nonceHandler.ts b/src/components/core/utils/nonceHandler.ts index 0f8332909..9fdd86a98 100644 --- a/src/components/core/utils/nonceHandler.ts +++ b/src/components/core/utils/nonceHandler.ts @@ -120,7 +120,8 @@ export async function checkNonce( consumer: string, nonce: number, signature: string, - message: string + message: string, + chainId?: string | null ): Promise { try { // get nonce from db @@ -135,7 +136,8 @@ export async function checkNonce( previousNonce, // will return 0 if none exists consumer, signature, - message // String(ddoId + nonce) + message, // String(ddoId + nonce) + chainId ) if (validate.valid) { const updateStatus = await updateNonce(db, consumer, nonce) @@ -182,7 +184,8 @@ async function validateNonceAndSignature( existingNonce: number, consumer: string, signature: string, - message: string = null + message: string = null, + chainId?: string | null ): Promise { if (nonce <= existingNonce) { return { @@ -217,10 +220,10 @@ async function validateNonceAndSignature( // Try ERC-1271 (smart account) validation try { const config = await getConfiguration() - const firstChainId = Object.keys(config?.supportedNetworks || {})[0] - if (firstChainId) { + const targetChainId = chainId || Object.keys(config?.supportedNetworks || {})[0] + if (targetChainId && config?.supportedNetworks?.[targetChainId]) { const provider = new ethers.JsonRpcProvider( - config.supportedNetworks[firstChainId].rpc + config.supportedNetworks[targetChainId].rpc ) // Try custom hash format (for backward compatibility) diff --git a/src/components/database/AuthTokenDatabase.ts b/src/components/database/AuthTokenDatabase.ts index 159506124..662489a41 100644 --- a/src/components/database/AuthTokenDatabase.ts +++ b/src/components/database/AuthTokenDatabase.ts @@ -11,6 +11,7 @@ export interface AuthToken { created: Date validUntil: Date | null isValid: boolean + chainId?: string | null } export class AuthTokenDatabase extends AbstractDatabase { @@ -36,9 +37,10 @@ export class AuthTokenDatabase extends AbstractDatabase { token: string, address: string, validUntil: number | null = null, - createdAt: number + createdAt: number, + chainId?: string | null ): Promise { - await this.provider.createToken(token, address, createdAt, validUntil) + await this.provider.createToken(token, address, createdAt, validUntil, chainId) return token } diff --git a/src/components/database/sqliteAuthToken.ts b/src/components/database/sqliteAuthToken.ts index ac526dbe3..5f607dafd 100644 --- a/src/components/database/sqliteAuthToken.ts +++ b/src/components/database/sqliteAuthToken.ts @@ -7,7 +7,8 @@ interface AuthTokenDatabaseProvider { token: string, address: string, createdAt: number, - validUntil: number | null + validUntil: number | null, + chainId?: string | null ): Promise validateTokenEntry(token: string): Promise invalidateTokenEntry(token: string): Promise @@ -27,22 +28,32 @@ export class SQLiteAuthToken implements AuthTokenDatabaseProvider { address TEXT NOT NULL, createdAt DATETIME DEFAULT CURRENT_TIMESTAMP, validUntil DATETIME, - isValid BOOLEAN DEFAULT TRUE + isValid BOOLEAN DEFAULT TRUE, + chainId TEXT ) `) + + // Migration: Add chainId column if it doesn't exist + return new Promise((resolve) => { + this.db.run(`ALTER TABLE authTokens ADD COLUMN chainId TEXT`, (_err) => { + // Ignore error if column already exists + resolve() + }) + }) } createToken( token: string, address: string, createdAt: number, - validUntil: number | null = null + validUntil: number | null = null, + chainId?: string | null ): Promise { const insertSQL = ` - INSERT INTO authTokens (token, address, createdAt, validUntil) VALUES (?, ?, ?, ?) + INSERT INTO authTokens (token, address, createdAt, validUntil, chainId) VALUES (?, ?, ?, ?, ?) ` return new Promise((resolve, reject) => { - this.db.run(insertSQL, [token, address, createdAt, validUntil], (err) => { + this.db.run(insertSQL, [token, address, createdAt, validUntil, chainId], (err) => { if (err) { DATABASE_LOGGER.error(`Error creating auth token: ${err}`) reject(err) diff --git a/src/components/httpRoutes/auth.ts b/src/components/httpRoutes/auth.ts index ac2b0ef0a..68a44860d 100644 --- a/src/components/httpRoutes/auth.ts +++ b/src/components/httpRoutes/auth.ts @@ -15,7 +15,7 @@ authRoutes.post( express.json(), async (req, res) => { try { - const { signature, address, nonce, validUntil } = req.body + const { signature, address, nonce, validUntil, chainId } = req.body if (!signature || !address) { return res.status(400).json({ error: 'Missing required parameters' }) @@ -26,7 +26,8 @@ authRoutes.post( signature, address, nonce, - validUntil + validUntil, + chainId }) if (response.status.error) { @@ -49,7 +50,7 @@ authRoutes.post( express.json(), async (req, res) => { try { - const { signature, address, nonce, token } = req.body + const { signature, address, nonce, token, chainId } = req.body if (!signature || !address || !token) { return res.status(400).json({ error: 'Missing required parameters' }) @@ -60,7 +61,8 @@ authRoutes.post( signature, address, nonce, - token + token, + chainId }) if (response.status.error) {