diff --git a/package.json b/package.json
index 456223dee08034cbe119228cc247eb349527eb0e..55c168b5fa11cec254601c2d582f0fa7ff9d7f1a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "itc-ng",
-  "version": "1.5.2",
+  "version": "1.5.3",
   "scripts": {
     "ng": "ng",
     "start": "ng serve",
diff --git a/src/app/admin/admin-routing.module.ts b/src/app/admin/admin-routing.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..56b6f3523cfc793edd4a8aff11e75ce45ae87c1a
--- /dev/null
+++ b/src/app/admin/admin-routing.module.ts
@@ -0,0 +1,26 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import {WorkspaceComponent} from "./workspace.component";
+import {DummyComponent} from "./dummy/dummy.component";
+
+
+const routes: Routes = [
+  {
+    path: ':ws',
+    component: WorkspaceComponent,
+    children: [
+      {path: '', redirectTo: 'monitor', pathMatch: 'full'},
+      {path: 'files', component: DummyComponent},
+      {path: 'syscheck', component: DummyComponent},
+      {path: 'monitor', component: DummyComponent},
+      {path: 'results', component: DummyComponent},
+      {path: '**', component: DummyComponent}
+    ]
+  },
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class AdminRoutingModule { }
diff --git a/src/app/admin/admin.module.ts b/src/app/admin/admin.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..aa206843d2d185891d5a6baa123323a96572e379
--- /dev/null
+++ b/src/app/admin/admin.module.ts
@@ -0,0 +1,20 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { AdminRoutingModule } from './admin-routing.module';
+import { WorkspaceComponent } from './workspace.component';
+import { DummyComponent } from './dummy/dummy.component';
+
+
+@NgModule({
+  declarations: [WorkspaceComponent, DummyComponent],
+  imports: [
+    CommonModule,
+    AdminRoutingModule
+  ],
+  exports: [
+    WorkspaceComponent,
+    DummyComponent
+  ]
+})
+export class AdminModule { }
diff --git a/src/app/admin/dummy/dummy.component.css b/src/app/admin/dummy/dummy.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..fbf04dc85472b7854e6dee1985f6dc571362bef9
--- /dev/null
+++ b/src/app/admin/dummy/dummy.component.css
@@ -0,0 +1,4 @@
+p {
+  margin: 10px;
+  color: yellow;
+}
diff --git a/src/app/admin/dummy/dummy.component.html b/src/app/admin/dummy/dummy.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..0c34d90802a2d866a91462b5c9e54ad238600aeb
--- /dev/null
+++ b/src/app/admin/dummy/dummy.component.html
@@ -0,0 +1 @@
+<p>dummy works!</p>
diff --git a/src/app/admin/dummy/dummy.component.spec.ts b/src/app/admin/dummy/dummy.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..52111f871a88d73ccfbd11fdea147f3c92f26c4d
--- /dev/null
+++ b/src/app/admin/dummy/dummy.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DummyComponent } from './dummy.component';
+
+describe('DummyComponent', () => {
+  let component: DummyComponent;
+  let fixture: ComponentFixture<DummyComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ DummyComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(DummyComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/admin/dummy/dummy.component.ts b/src/app/admin/dummy/dummy.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..226b14bc7378dac188f17b15b047d24653e7d098
--- /dev/null
+++ b/src/app/admin/dummy/dummy.component.ts
@@ -0,0 +1,15 @@
+import { Component, OnInit } from '@angular/core';
+
+@Component({
+  selector: 'app-dummy',
+  templateUrl: './dummy.component.html',
+  styleUrls: ['./dummy.component.css']
+})
+export class DummyComponent implements OnInit {
+
+  constructor() { }
+
+  ngOnInit() {
+  }
+
+}
diff --git a/src/app/admin/workspace.component.css b/src/app/admin/workspace.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..6da29efa857cb699c343691414dd2ccda9286bfb
--- /dev/null
+++ b/src/app/admin/workspace.component.css
@@ -0,0 +1,4 @@
+p {
+  margin: 10px;
+  color: aliceblue;
+}
diff --git a/src/app/admin/workspace.component.html b/src/app/admin/workspace.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..806da3409b9da517e7b4d74540f2e0ce4006a307
--- /dev/null
+++ b/src/app/admin/workspace.component.html
@@ -0,0 +1,8 @@
+<p>WorkspaceComponent</p>
+<p>Eingeloggt als {{ (mds.loginData$ | async)?.loginname}}</p>
+<p>Workspace: {{myWorkspace}}</p>
+<p>&nbsp;</p>
+<p>Sorry - die Einbindung der Administrator-Funktionen in das Testcenter ist noch in Arbeit.</p>
+
+<hr/>
+<router-outlet></router-outlet>
diff --git a/src/app/admin/workspace.component.spec.ts b/src/app/admin/workspace.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4ea31a8f29e3256b71a7d1772483fae203751971
--- /dev/null
+++ b/src/app/admin/workspace.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { WorkspaceComponent } from './workspace.component';
+
+describe('WorkspaceComponent', () => {
+  let component: WorkspaceComponent;
+  let fixture: ComponentFixture<WorkspaceComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ WorkspaceComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(WorkspaceComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/admin/workspace.component.ts b/src/app/admin/workspace.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2f0cb6b3f30f22c89c0511b305411fd08ad3a146
--- /dev/null
+++ b/src/app/admin/workspace.component.ts
@@ -0,0 +1,30 @@
+import {Component, OnDestroy, OnInit} from '@angular/core';
+import {MainDataService} from "../maindata.service";
+import {ActivatedRoute} from "@angular/router";
+import {Subscription} from "rxjs";
+
+@Component({
+  templateUrl: './workspace.component.html',
+  styleUrls: ['./workspace.component.css']
+})
+export class WorkspaceComponent implements OnInit, OnDestroy {
+  private routingSubscription: Subscription = null;
+  public myWorkspace = -1;
+
+  constructor(
+    private route: ActivatedRoute,
+    public mds: MainDataService
+  ) { }
+
+  ngOnInit() {
+    this.routingSubscription = this.route.params.subscribe(params => {
+      this.myWorkspace = Number(params['ws']);
+    });
+  }
+
+  ngOnDestroy() {
+    if (this.routingSubscription !== null) {
+      this.routingSubscription.unsubscribe();
+    }
+  }
+}
diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 797af8d39201d19688467347ea6abd91e8e91b89..fc17a2f177864f38714c40fd98aa07d84a6c400b 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -1,4 +1,3 @@
-import { TestControllerComponent } from './test-controller';
 import { AboutComponent } from './about/about.component';
 import { StartComponent } from './start/start.component';
 import { NgModule } from '@angular/core';
@@ -10,6 +9,8 @@ const routes: Routes = [
   {path: 'start', component: StartComponent},
   {path: 'about', component: AboutComponent},
   {path: 'check', loadChildren: './sys-check/sys-check.module#SysCheckModule'},
+  {path: 'admin', loadChildren: './admin/admin.module#AdminModule'},
+  {path: 'superadmin', loadChildren: './superadmin/superadmin.module#SuperadminModule'},
   {path: 't', loadChildren: './test-controller/test-controller.module#TestControllerModule'}
 ];
 
diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index b68b0ea55cb20fc9f361d3755f65d551f0ea499f..cb7cd04fbd5cb01dc96994960b469d65466e7dde 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -20,10 +20,20 @@ export class AppComponent implements OnInit {
     private cts: CustomtextService
   ) { }
 
+  private static getStringFromLocalStorage(key: string) {
+    const storageEntry = localStorage.getItem(key);
+    if (storageEntry !== null) {
+      if (storageEntry.length > 0) {
+        return (storageEntry as string);
+      }
+    }
+    return ''
+  }
+
   ngOnInit() {
-    this.mds.setCustomtextsFromDefList(appconfig.customtextsApp);
-    this.mds.setCustomtextsFromDefList(appconfig.customtextsLogin);
-    this.mds.setCustomtextsFromDefList(appconfig.customtextsBooklet);
+    this.mds.addCustomtextsFromDefList(appconfig.customtextsApp);
+    this.mds.addCustomtextsFromDefList(appconfig.customtextsLogin);
+    this.mds.addCustomtextsFromDefList(appconfig.customtextsBooklet);
 
     // give a message to the central message broadcast
 
@@ -39,27 +49,31 @@ export class AppComponent implements OnInit {
 
     this.bs.getSysConfig().subscribe(sc => {
       this.mds.setDefaultCustomtexts(sc);
-      this.mds.setCustomtextsFromDefList(appconfig.customtextsApp);
+      this.mds.addCustomtextsFromDefList(appconfig.customtextsApp);
       // restore login status if stored in localStorage
-      const loginToken = localStorage.getItem('lt');
-      if (loginToken !== null) {
-        if (loginToken.length > 0) {
-          let personToken = localStorage.getItem('pt');
-          let bookletDbId = 0;
-          if (personToken !== null) {
-            if (personToken.length > 0) {
-              const bookletDbIdStr = localStorage.getItem('bi');
-              if (bookletDbIdStr !== null) {
-                bookletDbId = Number(bookletDbIdStr);
-              }
+      const adminToken = AppComponent.getStringFromLocalStorage('at');
+      if (adminToken) {
+        this.bs.getLoginDataAdmin(adminToken).subscribe(
+          (admindata: LoginData) => {
+            if (admindata instanceof ServerError) {
+              this.mds.setNewLoginData();
+            } else {
+              this.mds.setNewLoginData(admindata);
             }
-          } else {
-            personToken = '';
           }
-          let code = localStorage.getItem('c');
-          if (code === null) {
-            code = '';
+        );
+      } else {
+        const loginToken = AppComponent.getStringFromLocalStorage('lt');
+        if (loginToken) {
+          let personToken = AppComponent.getStringFromLocalStorage('pt');
+          let bookletDbId = 0;
+          if (personToken) {
+            const bookletDbIdStr = AppComponent.getStringFromLocalStorage('bi');
+            if (bookletDbIdStr) {
+              bookletDbId = Number(bookletDbIdStr);
+            }
           }
+          const code = AppComponent.getStringFromLocalStorage('c');
 
           // bookletDbId is not yet checked by getLoginData, only passed-through
           this.bs.getLoginData(loginToken, personToken, bookletDbId).subscribe(ld => {
@@ -81,13 +95,9 @@ export class AppComponent implements OnInit {
           });
         } else {
           this.mds.setNewLoginData();
-          this.mds.setCustomtextsFromDefList(appconfig.customtextsLogin);
-          this.mds.setCustomtextsFromDefList(appconfig.customtextsBooklet);
+          this.mds.addCustomtextsFromDefList(appconfig.customtextsLogin);
+          this.mds.addCustomtextsFromDefList(appconfig.customtextsBooklet);
         }
-      } else {
-        this.mds.setNewLoginData();
-        this.mds.setCustomtextsFromDefList(appconfig.customtextsLogin);
-        this.mds.setCustomtextsFromDefList(appconfig.customtextsBooklet);
       }
     });
   }
diff --git a/src/app/app.interfaces.ts b/src/app/app.interfaces.ts
index 2844088fb37aed179d878363dc7673b3eadb0108..e51bbcc375f69220ff9f68fb1244e09bfccdc5c5 100644
--- a/src/app/app.interfaces.ts
+++ b/src/app/app.interfaces.ts
@@ -15,6 +15,7 @@ export interface BookletListByCode {
 export interface LoginData {
   logintoken: string;
   loginname: string;
+  name: string; // TODO is loginname, but backend sends name if admin login
   mode: string;
   groupname: string;
   workspaceName: string;
@@ -25,6 +26,9 @@ export interface LoginData {
   bookletlabel: string;
   customTexts: KeyValuePair;
   costumTexts: KeyValuePair; // TODO when backend fixed then change here
+  admintoken: string;
+  workspaces: WorkspaceData[];
+  is_superadmin: boolean
 }
 
 export interface BookletStatus {
@@ -47,3 +51,9 @@ export interface KeyValuePair {
 export interface KeyValuePairNumber {
   [K: string]: number;
 }
+
+export interface WorkspaceData {
+  id: number;
+  name: string;
+  role: string;
+}
diff --git a/src/app/backend.service.ts b/src/app/backend.service.ts
index e232513003be230468f01728ec9d1c28eb87ab9f..74f8455f190d40826ed10a3fad84631db3878329 100644
--- a/src/app/backend.service.ts
+++ b/src/app/backend.service.ts
@@ -2,7 +2,7 @@
 import { Injectable, Inject } from '@angular/core';
 import { HttpClient } from '@angular/common/http';
 import { Observable, of } from 'rxjs';
-import { catchError } from 'rxjs/operators';
+import {catchError, switchMap} from 'rxjs/operators';
 import { LoginData, BookletStatus, PersonTokenAndBookletDbId, KeyValuePair } from './app.interfaces';
 import {ErrorHandler, ServerError} from "iqb-components";
 
@@ -10,12 +10,14 @@ import {ErrorHandler, ServerError} from "iqb-components";
 @Injectable()
 export class BackendService {
   private serverSlimUrl = '';
+  private serverSlimAdminUrl = '';
   private serverSlimUrl_Close = '';
 
   constructor(
     @Inject('SERVER_URL') private readonly serverUrl: string,
     private http: HttpClient) {
       this.serverSlimUrl = this.serverUrl + 'php_tc/login.php/';
+      this.serverSlimAdminUrl = this.serverUrl + 'admin/php/login.php/';
       this.serverSlimUrl_Close = this.serverUrl + 'php_tc/tc_post.php/';
       this.serverUrl = this.serverUrl + 'php_start/';
     }
@@ -24,10 +26,25 @@ export class BackendService {
   // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
   login(name: string, password: string): Observable<LoginData | ServerError> {
     return this.http
-      .post<LoginData>(this.serverSlimUrl + 'login', {n: name, p: password})
+        .post<LoginData>(this.serverSlimAdminUrl + 'login', {n: name, p: password})
         .pipe(
-          catchError(ErrorHandler.handle)
-        );
+          catchError(ErrorHandler.handle),
+          switchMap(myLoginData => {
+            if (myLoginData instanceof ServerError) {
+              if ((myLoginData as ServerError).code == 401) {
+                return this.http
+                  .post<LoginData>(this.serverSlimUrl + 'login', {n: name, p: password})
+                    .pipe(
+                      catchError(ErrorHandler.handle)
+                    );
+              } else {
+                return of(myLoginData)
+              }
+            } else {
+              return of(myLoginData);
+            }
+          })
+        )
   }
 
   // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
@@ -39,6 +56,14 @@ export class BackendService {
         );
   }
 
+  getLoginDataAdmin(adminToken: string): Observable<LoginData | ServerError> {
+    return this.http
+      .post<LoginData>(this.serverSlimAdminUrl + 'login', {at: adminToken})
+      .pipe(
+        catchError(ErrorHandler.handle)
+      );
+  }
+
   // BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
   getSysConfig(): Observable<KeyValuePair> {
     return this.http.get<KeyValuePair>(this.serverSlimUrl + 'sysconfig')
diff --git a/src/app/maindata.service.ts b/src/app/maindata.service.ts
index 452e6b221a26a4f4c5419bcb04a8d1aa8a78b842..0d6600cc17b71fb6c539de4779df1e5b8dd7dd21 100644
--- a/src/app/maindata.service.ts
+++ b/src/app/maindata.service.ts
@@ -9,20 +9,26 @@ import { appconfig, customtextKeySeparator, CustomTextsDefList } from './app.con
   providedIn: 'root'
 })
 export class MainDataService {
-  private static defaultLoginData: LoginData = {
-    logintoken: '',
-    persontoken: '',
-    mode: '',
-    groupname: '',
-    loginname: '',
-    workspaceName: '',
-    booklets: null,
-    code: '',
-    booklet: 0,
-    bookletlabel: '',
-    customTexts: {},
-    costumTexts: {}
-  };
+  private static get defaultLoginData(): LoginData {
+    return {
+      logintoken: '',
+      persontoken: '',
+      mode: '',
+      groupname: '',
+      loginname: '',
+      name: '',
+      workspaceName: '',
+      booklets: null,
+      code: '',
+      booklet: 0,
+      bookletlabel: '',
+      customTexts: {},
+      admintoken: '',
+      workspaces: [],
+      is_superadmin: false,
+      costumTexts: {}
+    }
+  }
 
   public loginData$ = new BehaviorSubject<LoginData>(MainDataService.defaultLoginData);
   public globalErrorMsg$ = new BehaviorSubject<ServerError>(null);
@@ -30,6 +36,15 @@ export class MainDataService {
   // set by app.component.ts
   public postMessage$ = new Subject<MessageEvent>();
 
+  public get adminToken(): string {
+    const myLoginData = this.loginData$.getValue();
+    if (myLoginData) {
+      return myLoginData.admintoken;
+    } else {
+      return '';
+    }
+  }
+
   constructor(
     private bs: BackendService,
     private cts: CustomtextService
@@ -37,56 +52,54 @@ export class MainDataService {
 
   // ensures consistency
   setNewLoginData(logindata?: LoginData) {
-    const myLoginData: LoginData = {
-      logintoken: MainDataService.defaultLoginData.logintoken,
-      persontoken: MainDataService.defaultLoginData.persontoken,
-      mode: MainDataService.defaultLoginData.mode,
-      groupname: MainDataService.defaultLoginData.groupname,
-      loginname: MainDataService.defaultLoginData.loginname,
-      workspaceName: MainDataService.defaultLoginData.workspaceName,
-      booklets: MainDataService.defaultLoginData.booklets,
-      code: MainDataService.defaultLoginData.code,
-      booklet: MainDataService.defaultLoginData.booklet,
-      bookletlabel: MainDataService.defaultLoginData.bookletlabel,
-      customTexts: {}, // always ignored except right after getting from backend!
-      costumTexts: {} // always ignored except right after getting from backend!
-    };
-
-    if (logindata) {
-      if (
-        (logindata.logintoken.length > 0) &&
-        (logindata.loginname.length > 0) &&
-        (logindata.mode.length > 0) &&
-        (logindata.groupname.length > 0) &&
-        (logindata.workspaceName.length > 0) &&
-        (logindata.booklets)) {
-
-          const validCodes = Object.keys(logindata.booklets);
-          if (validCodes.length > 0) {
-            myLoginData.logintoken = logindata.logintoken;
-            myLoginData.loginname = logindata.loginname;
-            myLoginData.mode = logindata.mode;
-            myLoginData.groupname = logindata.groupname;
-            myLoginData.workspaceName = logindata.workspaceName;
-            myLoginData.booklets = logindata.booklets;
-            if (logindata.code.length > 0) {
-              if (logindata.code in logindata.booklets) {
-                myLoginData.code = logindata.code;
-              }
+    const myLoginData: LoginData = MainDataService.defaultLoginData;
+    if (!logindata) {
+      logindata = MainDataService.defaultLoginData;
+    }
+
+    if ((logindata.admintoken)) { //.length > 0) && (logindata.name.length > 0)) {
+      myLoginData.admintoken = logindata.admintoken;
+      if (logindata.name) {
+        myLoginData.loginname = logindata.name;
+      } else {
+        myLoginData.loginname = logindata.loginname;
+      }
+      myLoginData.workspaces = logindata.workspaces;
+      myLoginData.is_superadmin = logindata.is_superadmin;
+    } else if (
+      (logindata.logintoken.length > 0) &&
+      (logindata.loginname.length > 0) &&
+      (logindata.mode.length > 0) &&
+      (logindata.groupname.length > 0) &&
+      (logindata.workspaceName.length > 0) &&
+      (logindata.booklets)) {
+
+        const validCodes = Object.keys(logindata.booklets);
+        if (validCodes.length > 0) {
+          myLoginData.logintoken = logindata.logintoken;
+          myLoginData.loginname = logindata.loginname;
+          myLoginData.mode = logindata.mode;
+          myLoginData.groupname = logindata.groupname;
+          myLoginData.workspaceName = logindata.workspaceName;
+          myLoginData.booklets = logindata.booklets;
+          if (logindata.code.length > 0) {
+            if (logindata.code in logindata.booklets) {
+              myLoginData.code = logindata.code;
             }
-            if (logindata.persontoken.length > 0) {
-              myLoginData.persontoken = logindata.persontoken;
-              myLoginData.booklet = logindata.booklet;
-              if (myLoginData.booklet > 0) {
-                myLoginData.bookletlabel = logindata.bookletlabel;
-              }
+          }
+          if (logindata.persontoken.length > 0) {
+            myLoginData.persontoken = logindata.persontoken;
+            myLoginData.booklet = logindata.booklet;
+            if (myLoginData.booklet > 0) {
+              myLoginData.bookletlabel = logindata.bookletlabel;
             }
           }
-      }
-
+        }
     }
+
     this.loginData$.next(myLoginData);
     localStorage.setItem('lt', myLoginData.logintoken);
+    localStorage.setItem('at', myLoginData.admintoken);
     localStorage.setItem('pt', myLoginData.persontoken);
     localStorage.setItem('bi', myLoginData.booklet.toString());
   }
@@ -144,7 +157,7 @@ export class MainDataService {
     return myLoginData.persontoken;
   }
 
-  public setCustomtextsFromDefList(customtextList: CustomTextsDefList) {
+  public addCustomtextsFromDefList(customtextList: CustomTextsDefList) {
     const myCustomTexts: {[key: string]: string} = {};
     for (const ct of Object.keys(customtextList.defList)) {
       myCustomTexts[customtextList.keyPrefix + customtextKeySeparator + ct] = customtextList.defList[ct].defaultvalue;
@@ -152,25 +165,27 @@ export class MainDataService {
     this.cts.addCustomTexts(myCustomTexts);
   }
 
-  public setDefaultCustomtexts(newTexts: {[key: string]: string; }) {
-    for (const ctKey of Object.keys(newTexts)) {
-      const sepIndex = ctKey.indexOf(customtextKeySeparator);
-      if (sepIndex > 1) {
-        const keyPrefix = ctKey.slice(0 , sepIndex - 1);
-        const keyId = ctKey.slice(sepIndex + 1);
-
-        switch (keyPrefix) {
-          case 'app': {
-            appconfig.customtextsApp.defList[keyId].defaultvalue = newTexts[ctKey];
-            break;
-          }
-          case 'login': {
-            appconfig.customtextsLogin.defList[keyId].defaultvalue = newTexts[ctKey];
-            break;
-          }
-          case 'booklet': {
-            appconfig.customtextsBooklet.defList[keyId].defaultvalue = newTexts[ctKey];
-            break;
+ public setDefaultCustomtexts(newTexts: {[key: string]: string;}) {
+    if (newTexts) {
+      for (const ctKey of Object.keys(newTexts)) {
+        const sepIndex = ctKey.indexOf(customtextKeySeparator);
+        if (sepIndex > 1) {
+          const keyPrefix = ctKey.slice(0 , sepIndex - 1);
+          const keyId = ctKey.slice(sepIndex + 1);
+
+          switch (keyPrefix) {
+            case 'app': {
+              appconfig.customtextsApp.defList[keyId].defaultvalue = newTexts[ctKey];
+              break;
+            }
+            case 'login': {
+              appconfig.customtextsLogin.defList[keyId].defaultvalue = newTexts[ctKey];
+              break;
+            }
+            case 'booklet': {
+              appconfig.customtextsBooklet.defList[keyId].defaultvalue = newTexts[ctKey];
+              break;
+            }
           }
         }
       }
diff --git a/src/app/start/start.component.html b/src/app/start/start.component.html
index b85a75db65caade77c30f97a3fd7d7ea30d6baba..c7b18b1fa9143f8edc1b2d19da7c29de525e1c52 100644
--- a/src/app/start/start.component.html
+++ b/src/app/start/start.component.html
@@ -1,6 +1,6 @@
 <div class="logo">
   <a [routerLink]="['/']">
-    <img src="assets/IQB-LogoA.png" matTooltip="Startseite"/>
+    <img src="assets/IQB-LogoA.png" matTooltip="Startseite" alt=""IQB-Logo/>
   </a>
 </div>
 <div class="page-body">
@@ -13,14 +13,14 @@
     <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
     <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="showLoginForm">
       <!-- - - - - - - - - - - - - - - - - -->
-      <form [formGroup]="testtakerloginform" (ngSubmit)="testtakerlogin()">
+      <form [formGroup]="testtakerloginform" (ngSubmit)="login()">
         <mat-card-title>Anmelden</mat-card-title>
         <mat-card-content fxLayout="column">
           <mat-form-field>
             <input matInput formControlName="testname" placeholder="Anmeldename" (keyup.enter)="pw.focus()">
           </mat-form-field>
           <mat-form-field>
-            <input matInput #pw type="password" formControlName="testpw" placeholder="Kennwort" (keyup.enter)="testtakerlogin()">
+            <input matInput #pw type="password" formControlName="testpw" placeholder="Kennwort" (keyup.enter)="login()">
           </mat-form-field>
         </mat-card-content>
         <mat-card-actions>
@@ -51,7 +51,7 @@
     <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="showBookletButtons">
       <mat-card-title>{{ bookletSelectTitle }}</mat-card-title>
       <mat-card-content>
-        <div fxLayout="row" fxLayoutGap="10px" fxLayout="column">
+        <div fxLayoutGap="10px" fxLayout="column">
           <p *ngIf="bookletlist.length === 0">
             Für diese Anmeldung wurde kein Test gefunden.
           </p>
@@ -79,7 +79,26 @@
       </mat-card-content>
     </mat-card>
 
-    <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
+      <mat-card fxFlex="0 0 400px" fxLayout="column" *ngIf="showAdminSelection">
+        <mat-card-title>Studie wählen</mat-card-title>
+        <mat-card-content>
+          <div fxLayoutGap="10px" fxLayout="column">
+            <p *ngIf="(mds.loginData$ | async)?.workspaces.length === 0">
+              Sie sind mit Administrator-Funktionen angemeldet. Aktuell sind keine Studien für Sie freigegeben.
+            </p>
+            <button mat-raised-button color="primary" (click)="buttonGotoWorkspace(ws)"
+                    *ngFor="let ws of (mds.loginData$ | async)?.workspaces">
+              {{ws.name}}
+            </button>
+          </div>
+        </mat-card-content>
+        <mat-card-actions>
+          <button mat-raised-button color="foreground" *ngIf="(mds.loginData$ | async)?.is_superadmin" [routerLink]="['/superadmin']">Nutzer/Arbeitsbereiche</button>
+          <button mat-raised-button color="foreground" (click)="resetLogin()">Neu anmelden</button>
+        </mat-card-actions>
+      </mat-card>
+
+      <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
     <!-- XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -->
     <mat-card fxFlex="0 2 400px" fxLayout="column" class="status">
       <mat-card-title>{{ 'app_title' | customtext:'app_title':cts.updateCount }}</mat-card-title>
diff --git a/src/app/start/start.component.ts b/src/app/start/start.component.ts
index c8a77cf1ad262d21260b718805f5842c0d59c636..3a21184c371af645f9e27acc2b49ec3fb2920c28 100644
--- a/src/app/start/start.component.ts
+++ b/src/app/start/start.component.ts
@@ -3,7 +3,7 @@ import { Subscription, forkJoin } from 'rxjs';
 import {CustomtextService, MessageDialogComponent, MessageDialogData, MessageType, ServerError} from 'iqb-components';
 import { MatDialog } from '@angular/material';
 import { BackendService } from '../backend.service';
-import { PersonTokenAndBookletDbId, LoginData } from '../app.interfaces';
+import {PersonTokenAndBookletDbId, LoginData, WorkspaceData} from '../app.interfaces';
 import { Router } from '@angular/router';
 import { Component, OnInit, OnDestroy } from '@angular/core';
 import { FormGroup, FormBuilder, Validators } from '@angular/forms';
@@ -21,6 +21,7 @@ export class StartComponent implements OnInit, OnDestroy {
   public showBookletButtons = false;
   public bookletlist: StartButtonData[] = [];
   public showTestRunningButtons = false;
+  public showAdminSelection = false;
 
   private loginDataSubscription: Subscription = null;
 
@@ -52,8 +53,21 @@ export class StartComponent implements OnInit, OnDestroy {
   ngOnInit() {
     this.loginDataSubscription = this.mds.loginData$.subscribe(logindata => {
       this.bookletlist = [];
-      if (logindata.logintoken.length > 0) {
+      if (logindata.admintoken.length > 0) {
+        this.showLoginForm = false;
+        this.showAdminSelection = true;
+        this.showCodeForm = false;
+        this.showBookletButtons = false;
+        this.showTestRunningButtons = false;
+        this.loginStatusText = [];
+        this.loginStatusText.push('Admin-Bereich ');
+        this.loginStatusText.push('angemeldet als ' + logindata.loginname);
+        if (logindata.is_superadmin) {
+          this.loginStatusText.push('Rechte auch für Anlegen/Löschen von Nutzern und Workspaces');
+        }
+      } else if (logindata.logintoken.length > 0) {
         // Statustext box
+        this.showAdminSelection = false;
         this.loginStatusText = [];
         this.loginStatusText.push('Studie: ' + logindata.workspaceName);
         this.loginStatusText.push('angemeldet als "' +
@@ -171,6 +185,7 @@ export class StartComponent implements OnInit, OnDestroy {
         this.loginStatusText = ['nicht angemeldet'];
         this.showBookletButtons = false;
         this.showCodeForm = false;
+        this.showAdminSelection = false;
         this.showLoginForm = true;
         this.showTestRunningButtons = false;
       }
@@ -188,14 +203,14 @@ export class StartComponent implements OnInit, OnDestroy {
   }
 
   // # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-  testtakerlogin() {
+  login() {
     this.dataLoading = true;
     this.bs.login(this.testtakerloginform.get('testname').value, this.testtakerloginform.get('testpw').value).subscribe(
       loginData => {
         if (loginData instanceof ServerError) {
           const e = loginData as ServerError;
           this.mds.globalErrorMsg$.next(e);
-          this.mds.setCustomtextsFromDefList(appconfig.customtextsLogin);
+          this.mds.addCustomtextsFromDefList(appconfig.customtextsLogin);
           // no change in other data
         } else {
           this.mds.globalErrorMsg$.next(null);
@@ -275,6 +290,14 @@ export class StartComponent implements OnInit, OnDestroy {
     this.mds.endBooklet();
   }
 
+  buttonGotoWorkspace(ws: WorkspaceData) {
+    if (ws.role === 'MO') {
+      this.router.navigateByUrl('/admin/' + ws.id.toString() + '/monitor');
+    } else {
+      this.router.navigateByUrl('/admin/' + ws.id.toString() + '/files');
+    }
+  }
+
   // % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % % %
   ngOnDestroy() {
     if (this.loginDataSubscription !== null) {
diff --git a/src/app/superadmin/superadmin-routing.module.ts b/src/app/superadmin/superadmin-routing.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d950d3690c7bd000b0469aacc6b937c32bae6887
--- /dev/null
+++ b/src/app/superadmin/superadmin-routing.module.ts
@@ -0,0 +1,17 @@
+import { NgModule } from '@angular/core';
+import { Routes, RouterModule } from '@angular/router';
+import {SuperadminComponent} from "./superadmin.component";
+
+
+const routes: Routes = [
+  {
+    path: '',
+    component: SuperadminComponent
+  }
+];
+
+@NgModule({
+  imports: [RouterModule.forChild(routes)],
+  exports: [RouterModule]
+})
+export class SuperadminRoutingModule { }
diff --git a/src/app/superadmin/superadmin.component.css b/src/app/superadmin/superadmin.component.css
new file mode 100644
index 0000000000000000000000000000000000000000..6da29efa857cb699c343691414dd2ccda9286bfb
--- /dev/null
+++ b/src/app/superadmin/superadmin.component.css
@@ -0,0 +1,4 @@
+p {
+  margin: 10px;
+  color: aliceblue;
+}
diff --git a/src/app/superadmin/superadmin.component.html b/src/app/superadmin/superadmin.component.html
new file mode 100644
index 0000000000000000000000000000000000000000..04ba540ada44067ff58dd17c42edfa52d094c846
--- /dev/null
+++ b/src/app/superadmin/superadmin.component.html
@@ -0,0 +1,4 @@
+<p>SuperadminComponent</p>
+<p>Eingeloggt als {{ (mds.loginData$ | async)?.loginname}}</p>
+<p>&nbsp;</p>
+<p>Sorry - die Einbindung der Administrator-Funktionen in das Testcenter ist noch in Arbeit.</p>
diff --git a/src/app/superadmin/superadmin.component.spec.ts b/src/app/superadmin/superadmin.component.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f81c64d011ad02b5c14497860bef5b5455066eea
--- /dev/null
+++ b/src/app/superadmin/superadmin.component.spec.ts
@@ -0,0 +1,25 @@
+import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SuperadminComponent } from './superadmin.component';
+
+describe('SuperadminComponent', () => {
+  let component: SuperadminComponent;
+  let fixture: ComponentFixture<SuperadminComponent>;
+
+  beforeEach(async(() => {
+    TestBed.configureTestingModule({
+      declarations: [ SuperadminComponent ]
+    })
+    .compileComponents();
+  }));
+
+  beforeEach(() => {
+    fixture = TestBed.createComponent(SuperadminComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+});
diff --git a/src/app/superadmin/superadmin.component.ts b/src/app/superadmin/superadmin.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..31822a1221fb46772c56b0741b29e6fead36cf06
--- /dev/null
+++ b/src/app/superadmin/superadmin.component.ts
@@ -0,0 +1,17 @@
+import { Component, OnInit } from '@angular/core';
+import {MainDataService} from "../maindata.service";
+
+@Component({
+  templateUrl: './superadmin.component.html',
+  styleUrls: ['./superadmin.component.css']
+})
+export class SuperadminComponent implements OnInit {
+
+  constructor(
+    public mds: MainDataService
+  ) { }
+
+  ngOnInit() {
+  }
+
+}
diff --git a/src/app/superadmin/superadmin.module.ts b/src/app/superadmin/superadmin.module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..42de5ceb17cb199f2d9db3c83516058a3b767d8c
--- /dev/null
+++ b/src/app/superadmin/superadmin.module.ts
@@ -0,0 +1,18 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+
+import { SuperadminRoutingModule } from './superadmin-routing.module';
+import { SuperadminComponent } from './superadmin.component';
+
+
+@NgModule({
+  declarations: [SuperadminComponent],
+  imports: [
+    CommonModule,
+    SuperadminRoutingModule
+  ],
+  exports: [
+    SuperadminComponent
+  ]
+})
+export class SuperadminModule { }
diff --git a/src/app/sys-check/start.component.html b/src/app/sys-check/start.component.html
index c4b9e78de787f89d799ee17731e0ff8f85700413..ca7c04bde32b020add633adf0cfd0dbc78b38d43 100644
--- a/src/app/sys-check/start.component.html
+++ b/src/app/sys-check/start.component.html
@@ -9,7 +9,7 @@
 <div class="page-body">
   <div fxLayout="row" fxLayoutAlign="center start">
     <mat-card fxFlex="0 2 500px">
-      <mat-card-title>System-Check: Starten {{ 'app_title' | customtext:'app_title':cts.updateCount }}</mat-card-title>
+      <mat-card-title>{{ 'app_title' | customtext:'app_title':cts.updateCount }}: System-Check</mat-card-title>
       <mat-card-content>
         <p>Hier können Sie ermitteln, ob das Computersystem, das Sie gerade benutzen, für
           die hier vorgesehenen Testungen geeignet ist.</p>
diff --git a/src/app/sys-check/start.component.ts b/src/app/sys-check/start.component.ts
index 15e0d60560e2e482de9947329d022531256abdcb..335fbb6f004a4cdb9ec64f538a624b54887a2e61 100644
--- a/src/app/sys-check/start.component.ts
+++ b/src/app/sys-check/start.component.ts
@@ -27,7 +27,6 @@ export class StartComponent implements OnInit {
     this.dataLoading = true;
     this.bs.getCheckConfigs().subscribe(myConfigs => {
       this.checkConfigList = myConfigs;
-      console.log(this.cts.getCustomText('app_title', 'the app-title'));
       this.dataLoading = false;
     });
   }
diff --git a/src/app/sys-check/unit-check/unit-check.component.ts b/src/app/sys-check/unit-check/unit-check.component.ts
index 4b653c3f2531373f13c53f4b11656beb954732ed..25f734c2a74e1afb3301696e0b62d300e3d26e41 100644
--- a/src/app/sys-check/unit-check/unit-check.component.ts
+++ b/src/app/sys-check/unit-check/unit-check.component.ts
@@ -7,6 +7,8 @@ import { Subscription, BehaviorSubject, combineLatest} from 'rxjs';
 import { UnitData } from '../sys-check.interfaces';
 import { ServerError } from 'iqb-components';
 
+declare var srcDoc: any;
+
 @Component({
   selector: 'iqb-unit-check',
   templateUrl: './unit-check.component.html',
@@ -168,11 +170,13 @@ export class UnitCheckComponent implements OnInit, OnDestroy {
   private createPlayerElement(playerCode: string): void {
 
     this.iFrameItemplayer = <HTMLIFrameElement>document.createElement('iframe');
-    this.iFrameItemplayer.setAttribute('srcdoc', playerCode);
+    // this.iFrameItemplayer.setAttribute('srcdoc', playerCode);
     this.iFrameItemplayer.setAttribute('sandbox', 'allow-forms allow-scripts allow-same-origin');
     this.iFrameItemplayer.setAttribute('class', 'unitHost');
     this.iFrameItemplayer.setAttribute('height', '100');
     this.iFrameHostElement.nativeElement.appendChild(this.iFrameItemplayer);
+    srcDoc.set(this.iFrameItemplayer, playerCode);
+
   }
 
   ngOnDestroy() {
diff --git a/src/app/test-controller/test-controller.component.ts b/src/app/test-controller/test-controller.component.ts
index 4a217e0694642820712b93fed605604671d7b569..6ee45dce9eb849e7077c572f9c730415ea737fc9 100644
--- a/src/app/test-controller/test-controller.component.ts
+++ b/src/app/test-controller/test-controller.component.ts
@@ -480,7 +480,7 @@ export class TestControllerComponent implements OnInit, OnDestroy {
           if (myData instanceof ServerError) {
             const e = myData as ServerError;
             this.mds.globalErrorMsg$.next(e);
-            this.mds.setCustomtextsFromDefList(appconfig.customtextsBooklet);
+            this.mds.addCustomtextsFromDefList(appconfig.customtextsBooklet);
             this.tcs.dataLoading = false;
           } else {
             const bookletData = myData as BookletData;
diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts
index df10906299fa3fa39d3ebc3ae178258620967f7e..59bddd5fde1ba9790a98f38f0a008e206215323c 100644
--- a/src/environments/environment.prod.ts
+++ b/src/environments/environment.prod.ts
@@ -5,5 +5,5 @@ export const environment = {
   testcenterUrl: '/',
   appName: 'IQB-Testcenter',
   appPublisher: 'IQB - Institut zur Qualitätsentwicklung im Bildungswesen',
-  appVersion: '1.5.2 - 12.2.2020'
+  appVersion: '1.5.3 - 20.2.2020'
 };