-
Notifications
You must be signed in to change notification settings - Fork 11
/
helpers.ts
123 lines (108 loc) · 3.18 KB
/
helpers.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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
export function isValidPort(port: number) {
// verify if port is a number.
if (typeof port !== "number" || isNaN(port)) {
return false;
}
// port cannot be negative.
if (port <= 0) {
return false;
}
const minPort = 1;
const maxPort = 65535;
// Verify if port is in range.
return port >= minPort && port <= maxPort;
}
/**
* Validate a bucket name.
* http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html
*/
export function isValidBucketName(bucket: string) {
if (typeof bucket !== "string") {
return false;
}
// bucket length should be less than and no more than 63
// characters long.
if (bucket.length < 3 || bucket.length > 63) {
return false;
}
// bucket with successive periods is invalid.
if (bucket.indexOf("..") > -1) {
return false;
}
// bucket cannot have ip address style.
if (bucket.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/)) {
return false;
}
// bucket should begin with alphabet/number and end with alphabet/number,
// with alphabet/number/.- in the middle.
if (bucket.match(/^[a-z0-9][a-z0-9.-]+[a-z0-9]$/)) {
return true;
}
return false;
}
/**
* check if objectName is a valid object name
* http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMetadata.html
*/
export function isValidObjectName(objectName: string) {
if (!isValidPrefix(objectName)) return false;
if (objectName.length === 0) return false;
return true;
}
// check if prefix is valid
export function isValidPrefix(prefix: string) {
if (typeof prefix !== "string") return false;
if (prefix.length > 1024) return false;
return true;
}
/**
* Convert some binary data to a hex string
*/
export function bin2hex(binary: Uint8Array) {
return Array.from(binary).map((b) => b.toString(16).padStart(2, "0")).join(
"",
);
}
export function sanitizeETag(etag = "") {
const replaceChars: Record<string, string> = {
'"': "",
""": "",
""": "",
""": "",
""": "",
};
return etag.replace(
/^("|"|")|("|"|")$/g,
(m) => replaceChars[m],
);
}
export function getVersionId(headers: Headers): string | null {
return headers.get("x-amz-version-id") ?? null;
}
/** Create a Date string with format: 'YYYYMMDDTHHmmss' + Z */
export function makeDateLong(date?: Date) {
date = date || new Date();
// Gives format like: '2017-08-07T16:28:59.889Z'
const dateStr = date.toISOString();
return dateStr.substr(0, 4) +
dateStr.substr(5, 2) +
dateStr.substr(8, 5) +
dateStr.substr(14, 2) +
dateStr.substr(17, 2) + "Z";
}
/** Create a Date string with format: 'YYYYMMDD' */
export function makeDateShort(date?: Date) {
date = date || new Date();
// Gives format like: '2017-08-07T16:28:59.889Z'
const dateStr = date.toISOString();
return dateStr.substr(0, 4) + dateStr.substr(5, 2) + dateStr.substr(8, 2);
}
export function getScope(region: string, date: Date) {
return `${makeDateShort(date)}/${region}/s3/aws4_request`;
}
export async function sha256digestHex(data: Uint8Array | string) {
if (!(data instanceof Uint8Array)) {
data = new TextEncoder().encode(data);
}
return bin2hex(new Uint8Array(await crypto.subtle.digest("SHA-256", data)));
}