Skip to content

Commit a919d84

Browse files
authored
Use signature or auth token for routes (#968)
* check auth and signature for routes * fix check commands * validation fix * add nonce in get download * change message paid * send correct msg in test * add correct signature * fix signature messages test * do not check log * sign download asset test * remove validation fields * lint fix
1 parent 9ee90df commit a919d84

20 files changed

Lines changed: 185 additions & 239 deletions

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"@libp2p/websockets": "^8.1.1",
7474
"@multiformats/multiaddr": "^10.2.0",
7575
"@oceanprotocol/contracts": "^2.3.0",
76-
"@oceanprotocol/ddo-js": "^0.1.0",
76+
"@oceanprotocol/ddo-js": "^0.1.1",
7777
"@types/lodash.clonedeep": "^4.5.7",
7878
"axios": "^1.8.4",
7979
"base58-js": "^2.0.0",

src/components/Auth/index.ts

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ export interface CommonValidation {
99
error: string
1010
}
1111

12+
export interface AuthValidation {
13+
token?: string
14+
address?: string
15+
nonce?: string
16+
signature?: string
17+
message?: string
18+
}
19+
1220
export class Auth {
1321
private authTokenDatabase: AuthTokenDatabase
1422

@@ -21,10 +29,6 @@ export class Auth {
2129
return config.jwtSecret
2230
}
2331

24-
public getMessage(address: string, nonce: string): string {
25-
return address + nonce
26-
}
27-
2832
async getJWTToken(address: string, nonce: string, createdAt: number): Promise<string> {
2933
const jwtToken = jwt.sign(
3034
{
@@ -68,17 +72,10 @@ export class Auth {
6872
* @param {string} message - The message to validate
6973
* @returns The validation result
7074
*/
71-
async validateAuthenticationOrToken({
72-
token,
73-
address,
74-
nonce,
75-
signature
76-
}: {
77-
token?: string
78-
address?: string
79-
nonce?: string
80-
signature?: string
81-
}): Promise<CommonValidation> {
75+
async validateAuthenticationOrToken(
76+
authValidation: AuthValidation
77+
): Promise<CommonValidation> {
78+
const { token, address, nonce, signature, message } = authValidation
8279
try {
8380
if (signature && address && nonce) {
8481
const oceanNode = OceanNode.getInstance()
@@ -87,7 +84,7 @@ export class Auth {
8784
address,
8885
parseInt(nonce),
8986
signature,
90-
this.getMessage(address, nonce)
87+
message
9188
)
9289

9390
if (!nonceCheckResult.valid) {

src/components/core/compute/getResults.ts

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { P2PCommandResponse } from '../../../@types/index.js'
22
import { CORE_LOGGER } from '../../../utils/logging/common.js'
33
import { CommandHandler } from '../handler/handler.js'
44
import { ComputeGetResultCommand } from '../../../@types/commands.js'
5-
import { checkNonce, NonceResponse } from '../utils/nonceHandler.js'
65
import {
76
buildInvalidRequestMessage,
87
validateCommandParameters,
@@ -12,13 +11,7 @@ import { isAddress } from 'ethers'
1211

1312
export class ComputeGetResultHandler extends CommandHandler {
1413
validate(command: ComputeGetResultCommand): ValidateParams {
15-
const validation = validateCommandParameters(command, [
16-
'consumerAddress',
17-
'signature',
18-
'nonce',
19-
'jobId',
20-
'index'
21-
])
14+
const validation = validateCommandParameters(command, ['jobId', 'index'])
2215
if (validation.valid) {
2316
if (command.consumerAddress && !isAddress(command.consumerAddress)) {
2417
return buildInvalidRequestMessage(
@@ -38,33 +31,17 @@ export class ComputeGetResultHandler extends CommandHandler {
3831
return validationResponse
3932
}
4033

41-
let error = null
42-
43-
// signature message to check against
44-
const message = task.consumerAddress + task.jobId + task.index.toString() + task.nonce
45-
const nonceCheckResult: NonceResponse = await checkNonce(
46-
this.getOceanNode().getDatabase().nonce,
34+
const authValidationResponse = await this.validateTokenOrSignature(
35+
task.authorization,
4736
task.consumerAddress,
48-
parseInt(task.nonce),
37+
task.nonce,
4938
task.signature,
50-
message // task.jobId + task.index.toString()
39+
String(task.consumerAddress + task.jobId + task.index.toString() + task.nonce)
5140
)
52-
53-
if (!nonceCheckResult.valid) {
54-
// eslint-disable-next-line prefer-destructuring
55-
error = nonceCheckResult.error
41+
if (authValidationResponse.status.httpStatus !== 200) {
42+
return authValidationResponse
5643
}
5744

58-
if (error) {
59-
CORE_LOGGER.logMessage(error, true)
60-
return {
61-
stream: null,
62-
status: {
63-
httpStatus: 400,
64-
error
65-
}
66-
}
67-
}
6845
// split jobId (which is already in hash-jobId format) and get the hash
6946
// then get jobId which might contain dashes as well
7047
const index = task.jobId.indexOf('-')

src/components/core/compute/getStreamableLogs.ts

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { P2PCommandResponse } from '../../../@types/index.js'
22
import { CORE_LOGGER } from '../../../utils/logging/common.js'
33
import { CommandHandler } from '../handler/handler.js'
44
import { ComputeGetStreamableLogsCommand } from '../../../@types/commands.js'
5-
import { checkNonce, NonceResponse } from '../utils/nonceHandler.js'
65
import { Stream } from 'stream'
76
import {
87
buildInvalidRequestMessage,
@@ -13,12 +12,7 @@ import { isAddress } from 'ethers'
1312

1413
export class ComputeGetStreamableLogsHandler extends CommandHandler {
1514
validate(command: ComputeGetStreamableLogsCommand): ValidateParams {
16-
const validation = validateCommandParameters(command, [
17-
'consumerAddress',
18-
'signature',
19-
'nonce',
20-
'jobId'
21-
])
15+
const validation = validateCommandParameters(command, ['jobId'])
2216
if (validation.valid) {
2317
if (command.consumerAddress && !isAddress(command.consumerAddress)) {
2418
return buildInvalidRequestMessage(
@@ -30,37 +24,22 @@ export class ComputeGetStreamableLogsHandler extends CommandHandler {
3024
}
3125

3226
async handle(task: ComputeGetStreamableLogsCommand): Promise<P2PCommandResponse> {
27+
const oceanNode = this.getOceanNode()
28+
3329
const validationResponse = await this.verifyParamsAndRateLimits(task)
3430
if (this.shouldDenyTaskHandling(validationResponse)) {
3531
return validationResponse
3632
}
37-
const oceanNode = this.getOceanNode()
38-
let error = null
3933

40-
// signature message to check against
41-
const message = task.consumerAddress + task.jobId + task.nonce
42-
const nonceCheckResult: NonceResponse = await checkNonce(
43-
oceanNode.getDatabase().nonce,
34+
const authValidationResponse = await this.validateTokenOrSignature(
35+
task.authorization,
4436
task.consumerAddress,
45-
parseInt(task.nonce),
37+
task.nonce,
4638
task.signature,
47-
message
39+
String(task.consumerAddress + task.jobId + task.nonce)
4840
)
49-
50-
if (!nonceCheckResult.valid) {
51-
// eslint-disable-next-line prefer-destructuring
52-
error = nonceCheckResult.error
53-
}
54-
55-
if (error) {
56-
CORE_LOGGER.logMessage(error, true)
57-
return {
58-
stream: null,
59-
status: {
60-
httpStatus: 400,
61-
error
62-
}
63-
}
41+
if (authValidationResponse.status.httpStatus !== 200) {
42+
return authValidationResponse
6443
}
6544

6645
// split jobId (which is already in hash-jobId format) and get the hash

src/components/core/compute/startCompute.ts

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,12 @@ import { FindDdoHandler } from '../handler/ddoHandler.js'
3232
// import { ProviderFeeValidation } from '../../../@types/Fees.js'
3333
import { isOrderingAllowedForAsset } from '../handler/downloadHandler.js'
3434
import { DDOManager } from '@oceanprotocol/ddo-js'
35-
import { getNonceAsNumber, checkNonce, NonceResponse } from '../utils/nonceHandler.js'
35+
import { getNonceAsNumber } from '../utils/nonceHandler.js'
3636
import { generateUniqueID } from '../../database/sqliteCompute.js'
3737

3838
export class PaidComputeStartHandler extends CommandHandler {
3939
validate(command: PaidComputeStartCommand): ValidateParams {
4040
const commandValidation = validateCommandParameters(command, [
41-
'consumerAddress',
42-
'signature',
43-
'nonce',
4441
'environment',
4542
'algorithm',
4643
'datasets',
@@ -64,6 +61,19 @@ export class PaidComputeStartHandler extends CommandHandler {
6461
if (this.shouldDenyTaskHandling(validationResponse)) {
6562
return validationResponse
6663
}
64+
65+
const authValidationResponse = await this.validateTokenOrSignature(
66+
task.authorization,
67+
task.consumerAddress,
68+
task.nonce,
69+
task.signature,
70+
String(task.consumerAddress + task.datasets[0]?.documentId + task.nonce)
71+
)
72+
73+
if (authValidationResponse.status.httpStatus !== 200) {
74+
return authValidationResponse
75+
}
76+
6777
try {
6878
const node = this.getOceanNode()
6979
// split compute env (which is already in hash-envId format) and get the hash
@@ -452,9 +462,6 @@ export class FreeComputeStartHandler extends CommandHandler {
452462
const commandValidation = validateCommandParameters(command, [
453463
'algorithm',
454464
'datasets',
455-
'consumerAddress',
456-
'signature',
457-
'nonce',
458465
'environment'
459466
])
460467
if (commandValidation.valid) {
@@ -468,34 +475,23 @@ export class FreeComputeStartHandler extends CommandHandler {
468475
}
469476

470477
async handle(task: FreeComputeStartCommand): Promise<P2PCommandResponse> {
478+
const thisNode = this.getOceanNode()
471479
const validationResponse = await this.verifyParamsAndRateLimits(task)
472480
if (this.shouldDenyTaskHandling(validationResponse)) {
473481
return validationResponse
474482
}
475-
const thisNode = this.getOceanNode()
476-
// Validate nonce and signature
477-
const nonceCheckResult: NonceResponse = await checkNonce(
478-
thisNode.getDatabase().nonce,
483+
484+
const authValidationResponse = await this.validateTokenOrSignature(
485+
task.authorization,
479486
task.consumerAddress,
480-
parseInt(task.nonce),
487+
task.nonce,
481488
task.signature,
482489
String(task.nonce)
483490
)
484-
485-
if (!nonceCheckResult.valid) {
486-
CORE_LOGGER.logMessage(
487-
'Invalid nonce or signature, unable to proceed: ' + nonceCheckResult.error,
488-
true
489-
)
490-
return {
491-
stream: null,
492-
status: {
493-
httpStatus: 500,
494-
error:
495-
'Invalid nonce or signature, unable to proceed: ' + nonceCheckResult.error
496-
}
497-
}
491+
if (authValidationResponse.status.httpStatus !== 200) {
492+
return authValidationResponse
498493
}
494+
499495
let engine = null
500496
try {
501497
// split compute env (which is already in hash-envId format) and get the hash

src/components/core/compute/stopCompute.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,7 @@ import { isAddress } from 'ethers'
1212

1313
export class ComputeStopHandler extends CommandHandler {
1414
validate(command: ComputeStopCommand): ValidateParams {
15-
const validation = validateCommandParameters(command, [
16-
'consumerAddress',
17-
'signature',
18-
'nonce',
19-
'jobId'
20-
])
15+
const validation = validateCommandParameters(command, ['jobId'])
2116
if (validation.valid) {
2217
if (!isAddress(command.consumerAddress)) {
2318
return buildInvalidRequestMessage(
@@ -33,6 +28,18 @@ export class ComputeStopHandler extends CommandHandler {
3328
if (this.shouldDenyTaskHandling(validationResponse)) {
3429
return validationResponse
3530
}
31+
32+
const authValidationResponse = await this.validateTokenOrSignature(
33+
task.authorization,
34+
task.consumerAddress,
35+
task.nonce,
36+
task.signature,
37+
String(task.consumerAddress + (task.jobId || ''))
38+
)
39+
if (authValidationResponse.status.httpStatus !== 200) {
40+
return authValidationResponse
41+
}
42+
3643
try {
3744
// split jobId (which is already in hash-jobId format) and get the hash
3845
// then get jobId which might contain dashes as well

src/components/core/handler/authHandler.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ export class CreateAuthTokenHandler extends CommandHandler {
3131
async handle(task: CreateAuthTokenCommand): Promise<P2PCommandResponse> {
3232
const { address, nonce, signature } = task
3333
const nonceDb = this.getOceanNode().getDatabase().nonce
34-
const auth = this.getOceanNode().getAuth()
3534
const validationResponse = await this.verifyParamsAndRateLimits(task)
3635
if (this.shouldDenyTaskHandling(validationResponse)) {
3736
return validationResponse
@@ -43,7 +42,7 @@ export class CreateAuthTokenHandler extends CommandHandler {
4342
address,
4443
parseInt(nonce),
4544
signature,
46-
auth.getMessage(address, nonce)
45+
String(address + nonce)
4746
)
4847

4948
if (!nonceCheckResult.valid) {
@@ -83,7 +82,6 @@ export class InvalidateAuthTokenHandler extends CommandHandler {
8382
async handle(task: InvalidateAuthTokenCommand): Promise<P2PCommandResponse> {
8483
const { address, nonce, signature, token } = task
8584
const nonceDb = this.getOceanNode().getDatabase().nonce
86-
const auth = this.getOceanNode().getAuth()
8785
const validationResponse = await this.verifyParamsAndRateLimits(task)
8886
if (this.shouldDenyTaskHandling(validationResponse)) {
8987
return validationResponse
@@ -95,7 +93,7 @@ export class InvalidateAuthTokenHandler extends CommandHandler {
9593
address,
9694
parseInt(nonce),
9795
signature,
98-
auth.getMessage(address, nonce)
96+
String(address + nonce)
9997
)
10098
if (!isValid) {
10199
return {

0 commit comments

Comments
 (0)