private init()

in authui-container/server/auth-server.ts [139:297]


  private init() {
    this.app.enable('trust proxy');
    // Oauth handler widget code.
    // Proxy these requests to <project>.firebaseapp.com.
    // set this up before adding json body parser to the app. This causes POST requests to fail as mentioned in
    // https://github.com/chimurai/http-proxy-middleware/issues/171#issuecomment-356218599
    this.fetchAuthDomainProxyTarget().then(authDomainProxyTarget => {
      log(`Proxy auth requests to target ${authDomainProxyTarget}`);
      this.app.use('/__/auth/', createProxyMiddleware({
        target: authDomainProxyTarget,
        // set to true to pass SSL cert checks.
        // This causes the SNI/Host Header of the proxy request to be set to the targetURL
        // '<project>.firebaseapp.com'.
        changeOrigin: true,
        logLevel: 'debug',
        onError: errorCallback
      }));
      // Support JSON-encoded bodies.
      this.app.use(bodyParser.json());
      // Support URL-encoded bodies.
      this.app.use(bodyParser.urlencoded({
        extended: true
      }));

      // Post requests needs bodyParser to be setup first.
      // Otherwise, URLs in the request payload are not parsed correctly.
      // Administrative API for writing a custom configuration to.
      // This will save the configuration in a predetermined GCS bucket.
      if (this.isAdminAllowed()) {
        this.app.post('/set_admin_config', (req: express.Request, res: express.Response) => {
          if (!req.headers.authorization ||
              req.headers.authorization.split(' ').length <= 1) {
            this.handleErrorResponse(res, ERROR_MAP.UNAUTHENTICATED);
          } else if (!isNonNullObject(req.body) ||
                    Object.keys(req.body).length === 0) {
            this.handleErrorResponse(res, ERROR_MAP.INVALID_ARGUMENT);
          } else {
            const accessToken = req.headers.authorization.split(' ')[1];
            try {
              // Validate config before saving it.
              DefaultUiConfigBuilder.validateConfig(req.body);
              this.setConfigForAdmin(accessToken, req.body).then(() => {
                res.set('Content-Type', 'application/json');
                res.send(JSON.stringify({
                  status: 200,
                  message: 'Changes successfully saved.',
                }));
              }).catch((err) => {
                this.handleError(res, err);
              });
            } catch (e) {
              this.handleErrorResponse(
                res,
                {
                  error: {
                    code: 400,
                    status: 'INVALID_ARGUMENT',
                    message: e.message || 'Invalid UI configuration.',
                  },
                });
            }
          }
        });
     }
    })

    // Static assets.
    // Note that in production, this is served from dist/server/auth-server.js.
    this.app.use('/static', express.static(path.join(__dirname, '../public')));

    // IAP sign-in flow.
    this.app.get('/', (req: express.Request, res: express.Response) => {
      // Serve content for signed in user.
      return serveContentForSignIn(req, res);
    });

    // Provide easy way for developer to determine the auth domain being used.
    // This is the location to which requests are being proxied. This is same as
    // the output of /gcipConfig authDomain, but it validates that the proxy target
    // was read correctly by the constructor/init() code.
    this.app.get('/authdomain-proxytarget', (req: express.Request, res: express.Response) => {
      this.fetchAuthDomainProxyTarget()
        .then((authDomainProxyTarget) => {
          res.set('Content-Type', 'text/html');
          res.end(authDomainProxyTarget);
        })
        .catch((err) => {
          this.handleError(res, err);
        });
    });

    // Provide easy way for developer to determine version.
    this.app.get('/versionz', (req: express.Request, res: express.Response) => {
      res.set('Content-Type', 'text/html');
      res.end(HOSTED_UI_VERSION);
    });

    // Developers can disable admin panel when deploying Cloud Run service.
    if (this.isAdminAllowed()) {
      // Administrative sign-in UI config customization.
      this.app.get('/admin', (req: express.Request, res: express.Response) => {
        res.set('Content-Type', 'text/html');
        res.end(templates.admin({}));
      });

      // Administrative API for reading the current app configuration.
      // This could be either saved in GCS (custom config), environment variable (custom config)
      // or in memory (default config).
      this.app.get('/get_admin_config', (req: express.Request, res: express.Response) => {
        if (!req.headers.authorization ||
            req.headers.authorization.split(' ').length <= 1) {
          this.handleErrorResponse(res, ERROR_MAP.UNAUTHENTICATED);
        } else {
          // Use the hostname of the request to figure out the URL of the hosted UI.
          // This should be used as authDomain in admin config, unless it was overridden to a different value.
          // This enables authDomain to be in the same origin as the sign-in UI.
          const accessToken = req.headers.authorization.split(' ')[1];
          this.getConfigForAdmin(accessToken, req.hostname).then((config) => {
            res.set('Content-Type', 'application/json');
            res.send(JSON.stringify(config || {}));
          }).catch((err) => {
            this.handleError(res, err);
          });
        }
      });
    }

    // Used to return the auth configuration (apiKey + authDomain).
    this.app.get('/gcipConfig', (req: express.Request, res: express.Response) => {
      this.gcipHandler.getGcipConfig()
        .then((gcipConfig) => {
          res.set('Content-Type', 'application/json');
          res.send(JSON.stringify(gcipConfig));
        })
        .catch((err) => {
          this.handleError(res, err);
        });
    });

    // Returns the custom config (if available) or the default config, needed to render
    // the sign-in UI for IAP.
    this.app.get('/config', (req: express.Request, res: express.Response) => {
      // Use the hostname of the request to figure out the URL of the hosted UI.
      // This should be used as authDomain in config, unless it was overridden to a different value.
      // This enables authDomain to be in the same origin as the sign-in UI.
      this.getFallbackConfig(req.hostname)
        .then((currentConfig) => {
          if (!currentConfig) {
            this.handleErrorResponse(res, ERROR_MAP.NOT_FOUND);
          } else {
            res.set('Content-Type', 'application/json');
            res.send(JSON.stringify(currentConfig));
          }
        })
        .catch((err) => {
          this.handleError(res, err);
        });
    });
  }