AccessKeySigner.ts 1.77 KB
Newer Older
1 2 3 4 5 6 7
import { DigestParts, DigestGenerationArtifacts } from './digest-objects'
import randomstring from 'randomstring'
import crypto from 'crypto'

export default class AccessKeySigner {
    constructor(public readonly accessKey: string, private readonly accessSecret: string) {}

Rohan Prabhu's avatar
Rohan Prabhu committed
8 9 10
    static Headers = {
        Nonce: 'Nonce',
        Date: 'Date',
11 12
        ContentMD5: 'Content-Md5',
        ContentType: 'Content-Type'
Rohan Prabhu's avatar
Rohan Prabhu committed
13 14
    }

15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
    public signRequest(digestParts: DigestParts): DigestGenerationArtifacts {
        const date = this.getDate(digestParts)
        const contentType = this.getContentType(digestParts)
        const nonce = this.getNonce(digestParts)

        const computePayload = [
            digestParts.method.toUpperCase(),
            contentType,
            digestParts.payloadMd5,
            date,
            digestParts.path,
            nonce
        ].join('\n')

        const digest = crypto
Rohan Prabhu's avatar
Rohan Prabhu committed
30
            .createHmac('SHA1', Buffer.from(this.accessSecret, 'base64'))
31 32 33
            .update(computePayload)
            .digest('base64')

Rohan Prabhu's avatar
Rohan Prabhu committed
34
        return new DigestGenerationArtifacts(nonce, date, `Auth ${this.accessKey}:${digest}`)
35 36 37 38 39 40 41 42 43 44 45 46 47 48
    }

    private getNonce(digestParts: DigestParts): string {
        if (digestParts.nonce !== undefined) {
            return digestParts.nonce
        } else {
            return randomstring.generate(32)
        }
    }

    private getContentType(digestParts: DigestParts): string {
        if (digestParts.contentType !== undefined) {
            return digestParts.contentType
        } else {
Rohan Prabhu's avatar
Rohan Prabhu committed
49
            return 'null'
50 51 52 53 54 55 56 57 58 59 60
        }
    }

    private getDate(digestParts: DigestParts): string {
        if (digestParts.date !== undefined) {
            return digestParts.date
        } else {
            return new Date().toUTCString()
        }
    }
}