/
Signer.ts
89 lines (80 loc) · 2.62 KB
/
Signer.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { HttpRequest } from "@aws-sdk/protocol-http";
import { SignatureV4 } from "@aws-sdk/signature-v4";
import { CredentialProvider, Credentials, HashConstructor, Provider } from "@aws-sdk/types";
import { formatUrl } from "@aws-sdk/util-format-url";
import { getRuntimeConfig as __getRuntimeConfig } from "./runtimeConfig";
export interface SignerConfig {
/**
* The AWS credentials to sign requests with. Uses the default credential provider chain if not specified.
*/
credentials?: Credentials | CredentialProvider;
/**
* The hostname of the database to connect to.
*/
hostname: string;
/**
* The port number the database is listening on.
*/
port: number;
/**
* The region the database is located in. Uses the region inferred from the runtime if omitted.
*/
region?: string;
/**
* The SHA256 hasher constructor to sign the request.
*/
sha256?: HashConstructor;
/**
* The username to login as.
*/
username: string;
}
/**
* The signer class that generates an auth token to a database.
*/
export class Signer {
private readonly credentials: Credentials | CredentialProvider;
private readonly hostname: string;
private readonly port: number;
private readonly protocol: string = "https:";
private readonly region: string | Provider<string>;
private readonly service: string = "rds-db";
private readonly sha256: HashConstructor;
private readonly username: string;
constructor(configuration: SignerConfig) {
const runtimeConfiguration = __getRuntimeConfig(configuration);
this.credentials = runtimeConfiguration.credentials;
this.hostname = runtimeConfiguration.hostname;
this.port = runtimeConfiguration.port;
this.region = runtimeConfiguration.region;
this.sha256 = runtimeConfiguration.sha256;
this.username = runtimeConfiguration.username;
}
public async getAuthToken(): Promise<string> {
const signer = new SignatureV4({
service: this.service,
region: this.region,
credentials: this.credentials,
sha256: this.sha256,
});
const request = new HttpRequest({
method: "GET",
protocol: this.protocol,
hostname: this.hostname,
port: this.port,
query: {
Action: "connect",
DBUser: this.username,
},
headers: {
host: `${this.hostname}:${this.port}`,
},
});
const presigned = await signer.presign(request, {
expiresIn: 900,
});
// RDS requires the scheme to be removed
// https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.html
return formatUrl(presigned).replace(`${this.protocol}//`, "");
}
}