CloudFront Functionsで一つの関数に複数サイトのBASIC認証情報をまとめて設定する方法

以下の内容を全文コピペして貼り付けると良いのだ
トリガーは `ViewerRequest` にするのだ
`getAuthMaps` 関数内に、設定したいサイトのホスト名と、BASIC認証のID/PWを適宜入力するのだ

特定のディレクトリ配下にだけBASIC認証をかけたい？知らね

```javascript
/**
 * Get basic auth informations
 *
 * @return {Array-object} maps
 */
function getAuthMaps()
{
    var maps = [
        { "hostname": "test.example.com",  "username": "onamae",  "password": "pasuwaado"  },
        { "hostname": "test.example2.com", "username": "onamae2", "password": "pasuwaado2" }
    ];
    return maps;
}

/**
 * Get specified basic auth information by hostname
 *
 * @param  {string} hostName
 * @return {object|false} item
 */
function getAuthInfoByHostName(hostName)
{
    var maps = getAuthMaps();
    var key = "hostname";
    var items = maps.filter(function(v){
        return v[key] === hostName;
    });

    var item = items.length > 0 ? items[0] : false;
    return item;
}

/**
 * Get base64 encoded token by username and password
 *
 * @param  {object|false} item
 * @return {string} authorization e.g. "Basic b25hbWFlOnBhc3V3YWFkbw=="
 */
function createAuthToken(item)
{
    if(! item) return false;

    var userName = item.username;
    var passWord = item.password;
    var token = (userName + ":" + passWord).toString("base64");

    var authorization = "Basic " + token;
    return authorization;
}

/**
 * Check user request is authenticated or not.
 *
 * @param  {object} request [should be cloudfront request formatted]
 * @return {boolean} isAuth
 */
function authorize(request)
{
    var headers = request.headers;
    var hostName = headers.host.value;

    var item = getAuthInfoByHostName(hostName);
    var authorization = createAuthToken(item);

    var isAuth = authorization && headers.authorization && headers.authorization.value === authorization;
    return isAuth;
}

/**
 * It returns unauthorized error response.
 *
 * @return {object} response
 */
function showError401()
{
    var response = {
        statusCode: 401,
        statusDescription: "Unauthorized",
        headers: {
            "www-authenticate": {value: "Basic"}
        }
    };
    return response;
}

/**
 * Perform directory completion
 *
 * @param  {object} request [should be cloudfront request formatted]
 * @return {void}
 */
function directoryIndex(request)
{
    var uri = request.uri;

    // Check whether the URI is missing a file name.
    if (uri.endsWith('/')) {
        request.uri += 'index.html';
    }
    // Check whether the URI is missing a file extension.
    else if (!uri.includes('.')) {
        request.uri += '/index.html';
    }
}

/**
 * Do main process
 */
function handler(event)
{
    var request = event.request;

    // BASIC Authorization
    var isAuth = authorize(request);
    if (! isAuth) return showError401();

    // Directory Index
    //directoryIndex(request);

    return request;
}
```

CloudFrontはサブディレクトリのインデックス補完がないので、
`/foo/bar/` にアクセスしても 403エラーになります。
`/foo/bar/` にアクセスした時に `/foo/bar/index.html` を読み込むようにインデックス補完がしたい場合、
`handler` メソッド内にある `directoryIndex` 関数のコメントアウトを解除してください。

ネットに書いてある記事はひとつの関数に
ひとつのサイトのBASIC認証情報をハードコーディングしているものが多く、
同じ記述の関数を何個も量産するのもな～と思ったので、CloudFront Functionsの練習がてら作成。

`const` や `let` や `btoa` や `Buffer.from` が使えなくてアレって思った。