public setupRoutes()

in server/auth/types/basic/routes.ts [38:228]


  public setupRoutes() {
    // bootstrap an empty page so that browser app can render the login page
    // using client side routing.
    this.coreSetup.http.resources.register(
      {
        path: LOGIN_PAGE_URI,
        validate: false,
        options: {
          authRequired: false,
        },
      },
      async (context, request, response) => {
        this.sessionStorageFactory.asScoped(request).clear();
        const clearOldVersionCookie = clearOldVersionCookieValue(this.config);
        return response.renderAnonymousCoreApp({
          headers: {
            'set-cookie': clearOldVersionCookie,
          },
        });
      }
    );

    // login using username and password
    this.router.post(
      {
        path: API_AUTH_LOGIN,
        validate: {
          body: schema.object({
            username: schema.string(),
            password: schema.string(),
          }),
        },
        options: {
          authRequired: false,
        },
      },
      async (context, request, response) => {
        const forbiddenUsernames: string[] = this.config.auth.forbidden_usernames;
        if (forbiddenUsernames.indexOf(request.body.username) > -1) {
          context.security_plugin.logger.error(
            `Denied login for forbidden username ${request.body.username}`
          );
          return response.badRequest({
            // Cannot login using forbidden user name.
            body: 'Invalid username or password',
          });
        }

        let user: User;
        try {
          user = await this.securityClient.authenticate(request, {
            username: request.body.username,
            password: request.body.password,
          });
        } catch (error) {
          context.security_plugin.logger.error(`Failed authentication: ${error}`);
          return response.unauthorized({
            headers: {
              'www-authenticate': error.message,
            },
          });
        }

        this.sessionStorageFactory.asScoped(request).clear();
        const encodedCredentials = Buffer.from(
          `${request.body.username}:${request.body.password}`
        ).toString('base64');
        const sessionStorage: SecuritySessionCookie = {
          username: user.username,
          credentials: {
            authHeaderValue: `Basic ${encodedCredentials}`,
          },
          authType: 'basicauth',
          isAnonymousAuth: false,
          expiryTime: Date.now() + this.config.session.ttl,
        };

        if (this.config.multitenancy?.enabled) {
          const selectTenant = resolveTenant(
            request,
            user.username,
            user.tenants,
            this.config,
            sessionStorage
          );
          sessionStorage.tenant = selectTenant;
        }
        this.sessionStorageFactory.asScoped(request).set(sessionStorage);

        return response.ok({
          body: {
            username: user.username,
            tenants: user.tenants,
            roles: user.roles,
            backendroles: user.backendRoles,
            selectedTenants: this.config.multitenancy?.enabled ? sessionStorage.tenant : undefined,
          },
        });
      }
    );

    // logout
    this.router.post(
      {
        path: API_AUTH_LOGOUT,
        validate: false,
        options: {
          authRequired: false,
        },
      },
      async (context, request, response) => {
        this.sessionStorageFactory.asScoped(request).clear();
        return response.ok({
          body: {},
        });
      }
    );

    // anonymous auth
    this.router.get(
      {
        path: `/auth/anonymous`,
        validate: false,
        options: {
          authRequired: false,
        },
      },
      async (context, request, response) => {
        if (this.config.auth.anonymous_auth_enabled) {
          let user: User;
          const path: string = `${request.url.path}`;
          // If the request contains no redirect path, simply redirect to basepath.
          let redirectUrl: string = this.coreSetup.http.basePath.serverBasePath
            ? this.coreSetup.http.basePath.serverBasePath
            : '/';
          const requestQuery = request.url.query as ParsedUrlQueryParams;
          if (requestQuery.nextUrl !== undefined) {
            redirectUrl = requestQuery.nextUrl;
          }
          context.security_plugin.logger.info('The Redirect Path is ' + redirectUrl);
          try {
            user = await this.securityClient.authenticateWithHeaders(request, {});
          } catch (error) {
            context.security_plugin.logger.error(
              `Failed authentication: ${error}. Redirecting to Login Page`
            );
            return response.redirected({
              headers: {
                location: `${this.coreSetup.http.basePath.serverBasePath}${LOGIN_PAGE_URI}`,
              },
            });
          }

          this.sessionStorageFactory.asScoped(request).clear();
          const sessionStorage: SecuritySessionCookie = {
            username: user.username,
            authType: 'basicauth',
            isAnonymousAuth: true,
            expiryTime: Date.now() + this.config.session.ttl,
          };

          if (this.config.multitenancy?.enabled) {
            const selectTenant = resolveTenant(
              request,
              user.username,
              user.tenants,
              this.config,
              sessionStorage
            );
            sessionStorage.tenant = selectTenant;
          }
          this.sessionStorageFactory.asScoped(request).set(sessionStorage);

          return response.redirected({
            headers: {
              location: `${redirectUrl}`,
            },
          });
        } else {
          context.security_plugin.logger.error(
            'Anonymous auth is disabled. Redirecting to Login Page'
          );
          return response.redirected({
            headers: {
              location: `${this.coreSetup.http.basePath.serverBasePath}${LOGIN_PAGE_URI}`,
            },
          });
        }
      }
    );
  }