Skip to content

Commit b941a50

Browse files
committed
Cleanup
1 parent f9f303d commit b941a50

File tree

8 files changed

+74
-63
lines changed

8 files changed

+74
-63
lines changed

src/allow-methods.ts

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/allowed-method.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { IncomingMessage, ServerResponse } from 'micri';
2+
import { sendError } from './error';
3+
4+
// These methods are allowd for static resources: files and folder listings.
5+
const ALLOW_METHODS = ['GET', 'HEAD', 'OPTIONS'];
6+
const ALLOW_METHODS_STR = ALLOW_METHODS.join(', ');
7+
8+
const ALLOW_ORIGIN = '*';
9+
const ALLOW_REQ_HEADERS = 'Accept, Accept-Encoding, Range';
10+
const EXPOSE_RES_HEADERS =
11+
'Accept-Ranges, Content-Range, Content-Length, Content-Type, Content-Encoding, Content-Disposition, Date, ETag, Transfer-Encoding, Server';
12+
13+
/**
14+
* Check that the request method is one of the allowed types for static resources.
15+
*/
16+
export default function allowedMethod(req: IncomingMessage, res: ServerResponse): boolean {
17+
if (!ALLOW_METHODS.includes(req.method || '')) {
18+
res.setHeader('Allow', ALLOW_METHODS_STR);
19+
sendError(req, res, 405, {
20+
code: 'method_not_allowed',
21+
message: 'Method not allowed',
22+
});
23+
24+
return false;
25+
}
26+
27+
if (req.method === 'OPTIONS') {
28+
res.writeHead(204, {
29+
'Access-Control-Allow-Origin': ALLOW_ORIGIN,
30+
'Access-Control-Allow-Methods': ALLOW_METHODS_STR,
31+
'Access-Control-Allow-Headers': ALLOW_REQ_HEADERS,
32+
'Access-Control-Expose-Headers': EXPOSE_RES_HEADERS,
33+
'Access-Control-Max-Age': '86400',
34+
});
35+
res.end();
36+
37+
return false;
38+
}
39+
40+
return true;
41+
}

src/fetch-graph-api.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ type OauthToken = {
1111
access_token: string;
1212
};
1313

14+
class GraphApiError extends Error {
15+
method: string;
16+
path: string;
17+
responseBody: string;
18+
19+
constructor(path: string, opts: FetchOptions, res: Response, body: string, message: string) {
20+
super(`${message} (${res.statusText})`);
21+
this.method = opts.method || 'GET';
22+
this.path = path;
23+
this.responseBody = body;
24+
}
25+
}
26+
1427
const RESOURCE = 'https://graph.microsoft.com/';
1528
const [TENANT_ID, CLIENT_ID, CLIENT_SECRET] = getEnv('TENANT_ID', 'CLIENT_ID', 'CLIENT_SECRET');
1629
let tokenPromise: Promise<OauthToken> | null;
@@ -28,19 +41,6 @@ async function getToken(): Promise<OauthToken> {
2841
return res.json();
2942
}
3043

31-
class GraphApiError extends Error {
32-
method: string;
33-
path: string;
34-
responseBody: string;
35-
36-
constructor(path: string, opts: FetchOptions, res: Response, body: string, message: string) {
37-
super(`${message} (${res.statusText})`);
38-
this.method = opts.method || 'GET';
39-
this.path = path;
40-
this.responseBody = body;
41-
}
42-
}
43-
4444
export default async function fetchAPI(path: string, opts: FetchOptions = {}) {
4545
if (!tokenPromise) {
4646
tokenPromise = getToken();

src/get-site-config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import { DirectoryListing, File, Folder } from './graph-api-types';
77

88
const [ROOT] = getEnv('ROOT');
99

10+
/**
11+
* SiteConfig can be set per each domain.
12+
*/
1013
export type SiteConfig = {
1114
/**
1215
* Custom error page file paths.

src/index.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,33 +9,30 @@ import serveUri from './serve-uri';
99
import { sendError } from './error';
1010

1111
const [ROOT] = getEnv('ROOT');
12+
const HOSTNAME_RE = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
1213

1314
const server = micri(async (req: IncomingMessage, res: ServerResponse) => {
1415
accesslog(req, res);
1516

16-
const url = parse(req.url || '/', true);
17+
const pathname = parse(req.url || '/', true).pathname || '';
1718
const host = req.headers.host?.split(':')[0] || '';
1819

19-
if (
20-
host === '' ||
21-
!/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/.test(
22-
host
23-
)
24-
) {
20+
if (host === '' || !HOSTNAME_RE.test(host)) {
2521
return sendError(req, res, 400, {
2622
code: 'invalid_host',
2723
message: 'Invalid Host',
2824
});
2925
}
3026

3127
const siteConfig = await getSiteConfig(host);
32-
return serveUri(req, res, host, url.pathname || '', siteConfig);
28+
return serveUri(req, res, host, pathname, siteConfig);
3329
});
3430

3531
server.listen(process.env.PORT || 3000);
3632

33+
// Start authentication on startup to minimize the effect to serving traffic.
3734
apiFetch(`${ROOT}:`)
38-
.then(() => console.log(`Authenticated`)) // eslint-disable-line no-console
35+
.then(() => console.log('Authenticated')) // eslint-disable-line no-console
3936
.catch((err: Error) => {
4037
console.error(err); // eslint-disable-line no-console
4138
process.exit(1);

src/send-file-list.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import { send, IncomingMessage, ServerResponse } from 'micri';
22
import { parseAll } from '@hapi/accept';
3-
import allowMethods from './allow-methods';
3+
import allowedMethod from './allowed-method';
44
import setVary from './set-vary';
55
import { File, Folder } from './graph-api-types';
66

7-
function getParent(path: string) {
7+
/**
8+
* Get path to the parent folder of path.
9+
*/
10+
function getParent(path: string): string {
811
const prev = path.split('/').slice(0, -1).join('/');
912

1013
return prev.length === 0 ? '/' : prev;
@@ -42,12 +45,12 @@ export default function sendFileList(
4245
res: ServerResponse,
4346
pathname: string,
4447
files: Array<File | Folder>
45-
) {
48+
): void {
4649
let types = ['*/*'];
4750

4851
// Some methods are not allowed here and some will need special
4952
// handling.
50-
if (!allowMethods(req, res)) {
53+
if (!allowedMethod(req, res)) {
5154
return;
5255
}
5356

src/send-file.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createHash } from 'crypto';
22
import { IncomingMessage, ServerResponse, send } from 'micri';
3-
import allowMethods from './allow-methods';
3+
import allowedMethod from './allowed-method';
44
import fetch from './fetch';
55
import setVary from './set-vary';
66
import { CACHE_CONTROL } from './config';
@@ -22,10 +22,10 @@ function makeReqHeaders(req: IncomingMessage) {
2222
return headers;
2323
}
2424

25-
export default async function sendFile(req: IncomingMessage, res: ServerResponse, file: File) {
25+
export default async function sendFile(req: IncomingMessage, res: ServerResponse, file: File): Promise<void> {
2626
// Some methods are not allowed here and some will need special
2727
// handling.
28-
if (!allowMethods(req, res)) {
28+
if (!allowedMethod(req, res)) {
2929
return;
3030
}
3131

src/set-vary.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
import { ServerResponse } from 'micri';
22

3-
export default (res: ServerResponse) => res.setHeader('Vary', 'Accept, Accept-Encoding, Range');
3+
export default (res: ServerResponse): void => res.setHeader('Vary', 'Accept, Accept-Encoding, Range');

0 commit comments

Comments
 (0)