118 lines
4.0 KiB
TypeScript
118 lines
4.0 KiB
TypeScript
import { Injectable } from '@angular/core';
|
|
import { Router } from '@angular/router';
|
|
|
|
import { environment } from 'environments/environment';
|
|
|
|
import { OperatorService, WhoAmI } from 'app/core/core-services/operator.service';
|
|
import { DEFAULT_AUTH_TYPE, UserAuthType } from 'app/shared/models/users/user';
|
|
import { DataStoreService } from './data-store.service';
|
|
import { HttpService } from './http.service';
|
|
import { OpenSlidesService } from './openslides.service';
|
|
|
|
/**
|
|
* Authenticates an OpenSlides user with username and password
|
|
*/
|
|
@Injectable({
|
|
providedIn: 'root'
|
|
})
|
|
export class AuthService {
|
|
/**
|
|
* Initializes the httpClient and the {@link OperatorService}.
|
|
*
|
|
* @param http HttpService to send requests to the server
|
|
* @param operator Who is using OpenSlides
|
|
* @param OpenSlides The openslides service
|
|
* @param router To navigate
|
|
*/
|
|
public constructor(
|
|
private http: HttpService,
|
|
private operator: OperatorService,
|
|
private OpenSlides: OpenSlidesService,
|
|
private router: Router,
|
|
private DS: DataStoreService
|
|
) {}
|
|
|
|
/**
|
|
* Try to log in a user with a given auth type
|
|
*
|
|
* - Type "default": username and password needed; the earlySuccessCallback will be called.
|
|
* - Type "saml": The windows location will be changed to the single-sign-on service initiator.
|
|
*/
|
|
public async login(
|
|
authType: UserAuthType,
|
|
username: string,
|
|
password: string,
|
|
earlySuccessCallback: () => void
|
|
): Promise<void> {
|
|
if (authType === 'default') {
|
|
const user = {
|
|
username: username,
|
|
password: password
|
|
};
|
|
const response = await this.http.post<WhoAmI>(environment.urlPrefix + '/users/login/', user);
|
|
earlySuccessCallback();
|
|
await this.OpenSlides.shutdown();
|
|
await this.operator.setWhoAmI(response);
|
|
await this.OpenSlides.afterLoginBootup(response.user_id);
|
|
await this.redirectUser(response.user_id);
|
|
} else if (authType === 'saml') {
|
|
window.location.href = environment.urlPrefix + '/saml/?sso'; // Bye
|
|
} else {
|
|
throw new Error(`Unsupported auth type "${authType}"`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Redirects the user to the page where he came from. Boots OpenSlides,
|
|
* if it wasn't done before.
|
|
*/
|
|
public async redirectUser(userId: number): Promise<void> {
|
|
if (!this.OpenSlides.booted) {
|
|
await this.OpenSlides.afterLoginBootup(userId);
|
|
}
|
|
|
|
let redirect = this.OpenSlides.redirectUrl ? this.OpenSlides.redirectUrl : '/';
|
|
|
|
const excludedUrls = ['login'];
|
|
if (excludedUrls.some(url => redirect.includes(url))) {
|
|
redirect = '/';
|
|
}
|
|
this.router.navigate([redirect]);
|
|
}
|
|
|
|
/**
|
|
* Login for guests.
|
|
*/
|
|
public async guestLogin(): Promise<void> {
|
|
this.redirectUser(null);
|
|
}
|
|
|
|
/**
|
|
* Logout function for both the client and the server.
|
|
*
|
|
* Will clear the datastore, update the current operator and
|
|
* send a `post`-request to `/apps/users/logout/'`. Restarts OpenSlides.
|
|
*/
|
|
public async logout(): Promise<void> {
|
|
const authType = this.operator.authType.getValue();
|
|
if (authType === DEFAULT_AUTH_TYPE) {
|
|
let response = null;
|
|
try {
|
|
response = await this.http.post<WhoAmI>(environment.urlPrefix + '/users/logout/', {});
|
|
} catch (e) {
|
|
// We do nothing on failures. Reboot OpenSlides anyway.
|
|
}
|
|
this.router.navigate(['/']);
|
|
await this.DS.clear();
|
|
await this.operator.setWhoAmI(response);
|
|
await this.OpenSlides.reboot();
|
|
} else if (authType === 'saml') {
|
|
await this.DS.clear();
|
|
await this.operator.setWhoAmI(null);
|
|
window.location.href = environment.urlPrefix + '/saml/?slo'; // Bye
|
|
} else {
|
|
throw new Error(`Unsupported auth type "${authType}"`);
|
|
}
|
|
}
|
|
}
|