Skip to content

Commit

Permalink
chore: add verify dev command
Browse files Browse the repository at this point in the history
  • Loading branch information
2fd committed Dec 14, 2021
1 parent 5d640ec commit 004e118
Show file tree
Hide file tree
Showing 3 changed files with 262 additions and 73 deletions.
186 changes: 186 additions & 0 deletions bin/verify.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import { AuthChain, AuthLinkType } from 'dcl-crypto'
import { red, gray, green, blue } from 'colors/safe'
import {
verifyTimestamp,
verifyMetadata,
verifySign,
createPayload,
verifyExpiration,
} from '../src/verify'

const [_runtime, _file, rawAuthChain] = process.argv

class Logger {
items: any[][] = []
constructor(public prefix: string = '') {}

skip(message: string, ...extra: any[]) {
this.items.push([this.prefix + gray(`❔ ${message}`), ...extra])
}

ok(message: string, ...extra: any[]) {
this.items.push([this.prefix + green(`✅ ${message}`), ...extra])
}

error(message: string, ...extra: any[]) {
this.items.push([this.prefix + red(`❌ ${message}:`), ...extra])
}

flush() {
for (const item of this.items) {
console.log(...item)
}
this.items = []
}
}

const logger = new Logger()

let failed = false
async function step<F extends (logger: Logger) => Record<string, any>>(
name: string,
fun: F
): Promise<ReturnType<F>> {
if (failed) {
logger.skip(name)
logger.flush()
return {} as any
}

const l = new Logger(' ')
try {
const result = await fun(l)
logger.ok(name)
logger.flush()
l.flush()
return result as any
} catch (err) {
failed = true
logger.error(name, blue(err.message))
logger.flush()
l.flush()
return {} as any
}
}

Promise.resolve().then(async () => {
const { authChain, method, pathname, timestamp, metadata } = await step(
'Verify authChain',
async (logger) => {
const authChain: AuthChain = JSON.parse(rawAuthChain)

if (authChain.length !== 3) {
throw new Error(`Malformed Auth Chain: must have 3 items`)
}

const signatureItem = authChain[2]
if (
signatureItem.type !== AuthLinkType.ECDSA_PERSONAL_SIGNED_ENTITY &&
signatureItem.type !== AuthLinkType.ECDSA_EIP_1654_SIGNED_ENTITY
) {
throw new Error(
`Malformed Auth Chain: unsupported type "${signatureItem.type}". Expected ${AuthLinkType.ECDSA_PERSONAL_SIGNED_ENTITY} or ${AuthLinkType.ECDSA_EIP_1654_SIGNED_ENTITY}`
)
}

let isValidPayload = true
let payload = signatureItem.payload
const method = payload.slice(0, payload.indexOf(':'))
payload = payload.slice(payload.indexOf(':') + 1)

const pathname = payload.slice(0, payload.indexOf(':'))
payload = payload.slice(payload.indexOf(':') + 1)

const rawTimestamp = payload.slice(0, payload.indexOf(':'))
payload = payload.slice(payload.indexOf(':') + 1)

const rawMetadata = payload
const methods = [
'get',
'head',
'post',
'put',
'delete',
'connect',
'options',
'trace',
'patch',
]
if (methods.includes(method)) {
logger.ok(`http method: ${blue(method)}`)
} else {
logger.error(
`Invalud chain method: "${method}" (expected: "${methods.join(
'", "'
)})"`
)
isValidPayload = false
}

if (pathname.startsWith('/')) {
logger.ok(`http pathname: ${blue(pathname)}`)
} else {
logger.error(
`Invalid chain pathname: "${pathname}", (expected: /${pathname})`
)
isValidPayload = false
}

let timestamp: number = 0
try {
timestamp = verifyTimestamp(rawTimestamp)
logger.ok(`timestamp: ${blue(String(timestamp))}`)
} catch (err) {
logger.error(err.message)
isValidPayload = false
}

let metadata: any
try {
metadata = verifyMetadata(rawMetadata)
logger.ok(`metadata: ${blue(rawMetadata)}`)
} catch (err) {
logger.error(err.message)
isValidPayload = false
}

if (!isValidPayload) {
throw new Error(`Malformed Auth Chain: invalid payload`)
}

return { authChain, method, pathname, timestamp, metadata }
}
)

await step('Verify signature', async (logger) => {
const payload = createPayload(
method,
pathname,
String(timestamp),
JSON.stringify(metadata)
)
const ownerAddress = await verifySign(authChain, payload)
logger.ok(`ownerAddress: ${blue(ownerAddress)}`)
return { ownerAddress }
})

await step(`Verify expiration`, async () => {
verifyExpiration(timestamp)
return {}
})

console.log()
})

// const authChain = extractAuthChain(headers)
// const timestamp = verifyTimestamp(headers[AUTH_TIMESTAMP_HEADER])
// const metadata = verifyMetadata(headers[AUTH_METADATA_HEADER])

// const payload = createPayload(
// method,
// path,
// headers[AUTH_TIMESTAMP_HEADER],
// headers[AUTH_METADATA_HEADER]
// )
// const ownerAddress = await verifySign(authChain, payload, options)
// await verifyExpiration(timestamp)
143 changes: 71 additions & 72 deletions package-lock.json

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

6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"scripts": {
"test": "jest",
"build": "rm -rf lib && tsc -p . -outDir lib --sourceMap false --skipLibCheck",
"verify": "ts-node bin/verify.ts",
"format": "prettier --write '**/*.{ts,js,json,md}'",
"semantic-release": "semantic-release",
"husky-setup": "husky install",
Expand All @@ -21,7 +22,9 @@
}
},
"release": {
"branches": ["main"]
"branches": [
"main"
]
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -53,6 +56,7 @@
"@types/koa": "^2.13.4",
"@types/passport-strategy": "^0.2.35",
"@well-known-components/interfaces": "^1.1.0",
"colors": "^1.4.0",
"express": "^4.17.1",
"husky": "^7.0.2",
"jest": "^27.2.4",
Expand Down

0 comments on commit 004e118

Please sign in to comment.