Skip to content

Commit

Permalink
[be] fix secrets parsing (#45)
Browse files Browse the repository at this point in the history
* some debugging logs

* treat secret as string when reading from manager

* using authorization instead of x-auth-token

* lower case header
  • Loading branch information
mat1asm authored Mar 27, 2024
1 parent db73714 commit 6c49738
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 16 deletions.
28 changes: 22 additions & 6 deletions backend/src/handlers/discord-signed-digest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,19 @@ export interface DiscordSignedDigestParams {
publicKey: string
}

let guardKeyPair: Keypair

export const signDiscordMessage = async (
event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
try {
const publicKey = (event.queryStringParameters ?? {})['publicKey']
validatePublicKey(publicKey)

const accessToken = event.headers['x-auth-token']
const accessToken =
event.headers['Authorization'] ??
event.headers['authorization'] ??
event.headers['x-auth-token']
const discordId = await getDiscordId(accessToken)

const claimant = new PublicKey(publicKey!)
Expand Down Expand Up @@ -48,14 +53,20 @@ export const signDiscordMessage = async (
}

async function loadDispenserGuard() {
if (guardKeyPair) {
return guardKeyPair
}

const secretData = await getDispenserKey()
const dispenserGuardKey = secretData.key

const dispenserGuard = Keypair.fromSecretKey(
Uint8Array.from(dispenserGuardKey)
)

return dispenserGuard
guardKeyPair = dispenserGuard
console.log('Loaded dispenser guard key')
return guardKeyPair
}

function validatePublicKey(publicKey?: string) {
Expand All @@ -80,13 +91,18 @@ function validatePublicKey(publicKey?: string) {
}
}

async function getDiscordId(accessToken?: string) {
if (!accessToken) {
throw new HandlerError(400, { error: 'Must provide discord auth token' })
async function getDiscordId(tokenHeaderValue?: string) {
if (!tokenHeaderValue) {
throw new HandlerError(403, { error: 'Must provide discord auth token' })
}

const tokenParts = tokenHeaderValue.split(' ')
if (tokenParts.length !== 2 || tokenParts[0] !== 'Bearer') {
throw new HandlerError(403, { error: 'Invalid authorization header' })
}

try {
const user = await getDiscordUser(accessToken)
const user = await getDiscordUser(tokenParts[1])
return user.id
} catch (err) {
throw new HandlerError(403, { error: 'Invalid discord access token' })
Expand Down
12 changes: 10 additions & 2 deletions backend/src/handlers/fund-transactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { HandlerError } from '../utils/errors'

export type FundTransactionRequest = Uint8Array[]

let funderWallet: NodeWallet

export const fundTransactions = async (
event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
Expand Down Expand Up @@ -63,10 +65,16 @@ function validateFundTransactions(transactions: unknown) {
}

async function loadFunderWallet(): Promise<NodeWallet> {
if (funderWallet) {
return funderWallet
}

const secretData = await getFundingKey()
const funderWalletKey = secretData.key

const keypair = Keypair.fromSecretKey(new Uint8Array(funderWalletKey))
const keypair = Keypair.fromSecretKey(Uint8Array.from(funderWalletKey))

return new NodeWallet(keypair)
funderWallet = new NodeWallet(keypair)
console.log('Loaded funder wallet')
return funderWallet
}
27 changes: 22 additions & 5 deletions backend/src/utils/secrets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,45 @@ import config from '../config'
const client = new SecretsManagerClient({ region: config.aws.region })

export async function getDispenserKey() {
let key: string
if (config.keys.dispenserGuard.key) {
return { key: JSON.parse(config.keys.dispenserGuard.key) }
console.log('Using dispenser guard key from config')
key = config.keys.dispenserGuard.key
}

return getSecret(config.keys.dispenserGuard.secretName)
key = await getSecretKey(config.keys.dispenserGuard.secretName, 'key')
return { key: JSON.parse(key) }
}

export async function getFundingKey() {
export async function getFundingKey(): Promise<{ key: Uint8Array }> {
let key: string
if (config.keys.funding.key) {
return { key: JSON.parse(config.keys.funding.key) }
console.log('Using funding key from config')
key = config.keys.funding.key
}

return getSecret(config.keys.funding.secretName)
key = await getSecretKey(config.keys.funding.secretName, 'key')
return { key: JSON.parse(key) }
}

export async function getSecretKey(secretName: string, keyName: string) {
const secret = await getSecret(secretName)
return secret[keyName]
}

export async function getSecret(secretName: string) {
try {
const command = new GetSecretValueCommand({ SecretId: secretName })
const response = await client.send(command)
if (response.SecretString) {
console.log(
`Retrieved secret: ${secretName}. ${response.SecretString.length} characters long`
)
return JSON.parse(response.SecretString)
} else if (response.SecretBinary) {
console.log(
`Retrieved binary secret: ${secretName}. ${response.SecretBinary.length} characters long`
)
// For binary secrets, use Buffer to decode
const buff = Buffer.from(response.SecretBinary.toString(), 'base64')
return JSON.parse(buff.toString('ascii'))
Expand Down
4 changes: 2 additions & 2 deletions backend/test/handlers/discord-signed-digest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const givenDownstreamServicesWork = () => {
}),
http.all('https://secretsmanager.us-east-2.amazonaws.com', () => {
return HttpResponse.json({
SecretString: JSON.stringify({ key: [...new Keypair().secretKey] })
SecretString: JSON.stringify({ key: `[${new Keypair().secretKey}]` })
})
})
)
Expand All @@ -83,7 +83,7 @@ const whenSignDiscordMessageCalled = async (
) => {
response = await signDiscordMessage({
queryStringParameters: queryParams,
headers: { 'x-auth-token': 'token' }
headers: { Authorization: 'Bearer token' }
} as unknown as APIGatewayProxyEvent)
}

Expand Down
2 changes: 1 addition & 1 deletion backend/test/handlers/fund-transactions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ const givenDownstreamServicesWork = () => {
server.use(
http.all('https://secretsmanager.us-east-2.amazonaws.com', () => {
return HttpResponse.json({
SecretString: JSON.stringify({ key: [...FUNDER_KEY.secretKey] })
SecretString: JSON.stringify({ key: `[${[...FUNDER_KEY.secretKey]}]` })
})
})
)
Expand Down

0 comments on commit 6c49738

Please sign in to comment.