Commit 1ac43e61 authored by Νίκος Κατσαούνος's avatar Νίκος Κατσαούνος

several updates

parents 9846d74b 2dff0c88
......@@ -12,3 +12,9 @@ casost.log_out_go:
_controller: '\Drupal\casost\Controller\CASLogout::logoutGo'
requirements:
_user_is_logged_in: 'TRUE'
casost.log_out_cas_go:
path: /cas/logoutcas
defaults:
_controller: '\Drupal\casost\Controller\CASLogout::logoutCasGo'
requirements:
_access: 'TRUE'
......@@ -123,7 +123,7 @@ class CASLogin extends ControllerBase
}
$attributes = phpCAS::getAttributes();
/*
/*
$isAllowed = true;
$att1 = $attributes[$this->allowed1];
$att2 = $attributes[$this->allowed2];
......@@ -150,8 +150,8 @@ class CASLogin extends ControllerBase
}
if (!$found1 || !$found2) {
$isAllowed = false;
}
}
if (!$isAllowed) {
$response = new Response();
$response->setContent(t('Access is allowed only to official school accounts'));
......@@ -302,4 +302,4 @@ class CASLogin extends ControllerBase
return false;
}
}
\ No newline at end of file
}
......@@ -10,6 +10,7 @@ use Drupal\user\Entity\User;
use Drupal\Core\Database\Connection;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use phpCAS;
......@@ -38,11 +39,12 @@ class CASLogout extends ControllerBase
protected $connection;
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
QueryFactory $entity_query,
Connection $connection,
LoggerChannelFactoryInterface $loggerChannel)
{
EntityTypeManagerInterface $entityTypeManager,
QueryFactory $entity_query,
Connection $connection,
LoggerChannelFactoryInterface $loggerChannel
) {
$this->entityTypeManager = $entityTypeManager;
$this->entity_query = $entity_query;
$this->connection = $connection;
......@@ -56,14 +58,13 @@ class CASLogout extends ControllerBase
$container->get('entity.query'),
$container->get('database'),
$container->get('logger.factory')
);
);
}
public function logoutGo(Request $request)
{
$configRowName = 'casost_sch_sso_config';
try {
$configRowId = $request->query->get('config');
if ($configRowId) {
$configRowName = $configRowName.'_'.$configRowId;
......@@ -116,10 +117,15 @@ class CASLogout extends ControllerBase
$user->setPassword(uniqid('pw'));
$user->save();
$response = new Response();
$response->setContent("{\"message\": \"Server logout successful\",\"next\": \"{$this->logoutRedirectUrl}\"}");
$response->setStatusCode(Response::HTTP_OK);
$response->headers->set('Content-Type', 'application/json');
// $response = new Response();
// $response->setContent("{\"message\": \"Server logout successful\",\"next\": \"{$this->logoutRedirectUrl}\"}");
// $response->setStatusCode(Response::HTTP_OK);
// $response->headers->set('Content-Type', 'application/json');
$response = (new JsonResponse([
"message" => "Server logout successful",
"next" => "{$this->logoutRedirectUrl}"
]))->setStatusCode(Response::HTTP_OK);
session_unset();
session_destroy();
......@@ -136,7 +142,57 @@ class CASLogout extends ControllerBase
}
}
private function redirectForbidden($configRowName, $errorCode) {
public function logoutCasGo(Request $request)
{
$configRowName = 'casost_sch_sso_config';
try {
$configRowId = $request->query->get('config');
if ($configRowId) {
$configRowName = $configRowName.'_'.$configRowId;
}
$CASOSTConfigs = $this->entityTypeManager->getStorage('casost_config')->loadByProperties(array('name' => $configRowName));
$CASOSTConfig = reset($CASOSTConfigs);
if ($CASOSTConfig) {
$this->serverVersion = $CASOSTConfig->serverversion->value;
$this->serverHostname = $CASOSTConfig->serverhostname->value;
$this->serverPort = $CASOSTConfig->serverport->value;
$this->serverUri = $CASOSTConfig->serveruri->value === null ? '' : $CASOSTConfig->serveruri->value;
$this->redirectUrl = $CASOSTConfig->redirecturl->value;
$this->changeSessionId = $CASOSTConfig->changesessionid->value;
$this->logoutRedirectUrl = $CASOSTConfig->logoutredirecturl->value;
$this->CASServerCACert = $CASOSTConfig->casservercacert->value;
$this->CASServerCNValidate = $CASOSTConfig->casservercnvalidate->value;
$this->noCASServerValidation = $CASOSTConfig->nocasservervalidation->value;
$this->proxy = $CASOSTConfig->proxy->value;
$this->handleLogoutRequests = $CASOSTConfig->handlelogoutrequests->value;
$this->CASLang = $CASOSTConfig->caslang->value;
$this->allowed1 = $CASOSTConfig->allowed1->value;
$this->allowed1Value = $CASOSTConfig->allowed1value->value;
$this->allowed2 = $CASOSTConfig->allowed2->value;
$this->allowed2Value = $CASOSTConfig->allowed2value->value;
} else {
return $this->redirectForbidden($configRowName, '7001');
}
$response = new Response();
$response->setContent("{\"message\": \"Server logout continue\",\"next\": \"{$this->logoutRedirectUrl}\"}");
$response->setStatusCode(Response::HTTP_OK);
$response->headers->set('Content-Type', 'application/json');
session_unset();
session_destroy();
\Drupal::service('page_cache_kill_switch')->trigger();
session_start();
return $response;
} catch (\Exception $e) {
$this->logger->warning($e->getMessage());
return $this->redirectForbidden($configRowName, '8000');
}
}
private function redirectForbidden($configRowName, $errorCode)
{
session_unset();
session_destroy();
\Drupal::service('page_cache_kill_switch')->trigger();
......@@ -146,4 +202,4 @@ class CASLogout extends ControllerBase
return new RedirectResponseWithCookieExt($this->redirectUrl .'&error_code=' . $errorCode, 302, []);
}
}
}
\ No newline at end of file
}
......@@ -68,6 +68,7 @@ class ApplicationSubmit extends ControllerBase {
], Response::HTTP_FORBIDDEN);
}
$student = array(
'langcode' => 'el',
'student_record_id' => 0,
......@@ -94,9 +95,10 @@ class ApplicationSubmit extends ControllerBase {
'certificatetype' => $applicationForm[0]['certificatetype'],
'graduation_year' => $applicationForm[0]['graduation_year'],
'lastschool_registrynumber' => $applicationForm[0]['lastschool_registrynumber'],
'lastschool_unittypeid' => $applicationForm[0]['lastschool_unittypeid'],
'lastschool_schoolname' => $applicationForm[0]['lastschool_schoolname'],
'lastschool_schoolyear' => $applicationForm[0]['lastschool_schoolyear'],
'lastschool_class' => $applicationForm[0]['lastschool_class'],
'currentepal' => $applicationForm[0]['currentepal'],
'currentclass' => $applicationForm[0]['currentclass'],
'guardian_name' => $applicationForm[0]['cu_name'],
'guardian_surname' => $applicationForm[0]['cu_surname'],
......@@ -111,6 +113,22 @@ class ApplicationSubmit extends ControllerBase {
return $this->respondWithStatus([
"error_code" => $errorCode ], Response::HTTP_OK);
}
$lastSchoolRegistryNumber = $student['lastschool_registrynumber'];
$lastSchoolYear = (int)(substr($student['lastschool_schoolyear'], -4));
if ((int)date("Y") === $lastSchoolYear && (int)$student['lastschool_unittypeid'] === 5) {
$epalSchools = $this->entityTypeManager->getStorage('eepal_school')->loadByProperties(array('registry_no' => $lastSchoolRegistryNumber));
$epalSchool = reset($epalSchools);
if (!$epalSchool){
return $this->respondWithStatus([
"error_code" => 4004
], Response::HTTP_FORBIDDEN);
} else {
$student['currentepal'] = $epalSchool->id();
}
} else {
$student['currentepal'] = 0;
}
$entity_storage_student = $this->entityTypeManager->getStorage('epal_student');
$entity_object = $entity_storage_student->create($student);
$entity_storage_student->save($entity_object);
......@@ -176,6 +194,9 @@ class ApplicationSubmit extends ControllerBase {
if(!$student["agreement"]) {
return 1001;
}
if(!$student["lastschool_schoolyear"] || strlen($student["lastschool_schoolyear"]) !== 9) {
return 1002;
}
return 0;
}
}
......@@ -362,6 +362,13 @@ public function SaveCapacity(Request $request,$taxi,$tomeas,$specialit)
{
$postData = json_decode($content);
$cap = $postData->capacity;
if ($cap<= 0 || $cap > 99)
{
return $this->respondWithStatus([
'message' => t("Number out of limits!"),
], Response::HTTP_BAD_REQUEST);
}
if (($tomeas == 0) && ($specialit == 0))
{
$CapacityPerClass = $this->entityTypeManager->getStorage('eepal_school')->loadByProperties(array('id' => $schoolid ));
......
......@@ -21,19 +21,18 @@ class MinistryLogin extends ControllerBase
//protected $connection;
public function __construct(
EntityTypeManagerInterface $entityTypeManager,
//QueryFactory $entity_query,
// $connection,
LoggerChannelFactoryInterface $loggerChannel)
{
EntityTypeManagerInterface $entityTypeManager,
//QueryFactory $entity_query,
// $connection,
LoggerChannelFactoryInterface $loggerChannel
) {
$this->entityTypeManager = $entityTypeManager;
//$this->entity_query = $entity_query;
//$this->connection = $connection;
$this->logger = $loggerChannel->get('epal');
}
public static function create(ContainerInterface $container)
{
return new static(
......@@ -41,142 +40,127 @@ class MinistryLogin extends ControllerBase
//$container->get('entity.query'),
//$container->get('database'),
$container->get('logger.factory')
);
);
}
public function loginGo(Request $request)
{
try {
if (!$request->isMethod('POST')) {
return $this->respondWithStatus([
"message" => t("Method Not Allowed")
], Response::HTTP_METHOD_NOT_ALLOWED);
}
try {
if (!$request->isMethod('POST')) {
return $this->respondWithStatus([
"message" => t("Method Not Allowed")
], Response::HTTP_METHOD_NOT_ALLOWED);
}
//user validation
//Note: $authToken = $postData->username
$authToken = $request->headers->get('PHP_AUTH_USER');
$users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken));
$user = reset($users);
if (!$user) {
return $this->respondWithStatus([
//user validation
//Note: $authToken = $postData->username
$authToken = $request->headers->get('PHP_AUTH_USER');
$users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken));
$user = reset($users);
if (!$user) {
return $this->respondWithStatus([
'message' => t("User not found"),
], Response::HTTP_FORBIDDEN);
}
}
//user role validation
//$user = \Drupal\user\Entity\User::load($user->id());
$roles = $user->getRoles();
$validRole = false;
foreach ($roles as $role)
if ($role === "ministry") {
$validRole = true;
break;
}
if (!$validRole) {
return $this->respondWithStatus([
//user role validation
//$user = \Drupal\user\Entity\User::load($user->id());
$roles = $user->getRoles();
$validRole = false;
foreach ($roles as $role) {
if ($role === "ministry") {
$validRole = true;
break;
}
}
if (!$validRole) {
return $this->respondWithStatus([
'message' => t("User Invalid Role"),
], Response::HTTP_FORBIDDEN);
}
$currentRoleName = "supervisor";
}
$currentRoleName = "supervisor";
$postData = null;
if ($content = $request->getContent()) {
$postData = json_decode($content);
//return new RedirectResponse("/drupal-8.2.6/eepal/dist/" . '?auth_token=' . $postData->username .'&auth_role=supervisor', 302, []);
return $this->respondWithStatus([
$postData = null;
if ($content = $request->getContent()) {
$postData = json_decode($content);
//return new RedirectResponse("/drupal-8.2.6/eepal/dist/" . '?auth_token=' . $postData->username .'&auth_role=supervisor', 302, []);
return $this->respondWithStatus([
//'auth_token' => $postData->username,
//'userpassword' => $postData->userpassword,
//'auth_role' => $currentRoleName,
], Response::HTTP_OK);
}
else {
return $this->respondWithStatus([
'message' => t("post with no data"),
], Response::HTTP_BAD_REQUEST);
}
], Response::HTTP_OK);
} else {
return $this->respondWithStatus([
'message' => t("post with no data"),
], Response::HTTP_BAD_REQUEST);
}
} //end try
catch (\Exception $e) {
$this->logger->warning($e->getMessage());
$response = new Response();
$response->setContent('forbidden');
$response->setStatusCode(Response::HTTP_FORBIDDEN);
$response->headers->set('Content-Type', 'application/json');
return $response;
return $this->respondWithStatus([
'message' => 'forbidden',
], Response::HTTP_FORBIDDEN);
}
}
public function logoutGo(Request $request)
{
try {
if (!$request->isMethod('POST')) {
return $this->respondWithStatus([
"message" => t("Method Not Allowed")
try {
if (!$request->isMethod('POST')) {
return $this->respondWithStatus([
"message" => t("Method Not Allowed")
], Response::HTTP_METHOD_NOT_ALLOWED);
}
//user validation
//Note: $authToken = $postData->username
$authToken = $request->headers->get('PHP_AUTH_USER');
$users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken));
$user = reset($users);
if (!$user) {
return $this->respondWithStatus([
}
//user validation
//Note: $authToken = $postData->username
$authToken = $request->headers->get('PHP_AUTH_USER');
$users = $this->entityTypeManager->getStorage('user')->loadByProperties(array('name' => $authToken));
$user = reset($users);
if (!$user) {
return $this->respondWithStatus([
'message' => t("User not found"),
], Response::HTTP_FORBIDDEN);
}
//user role validation
//$user = \Drupal\user\Entity\User::load($user->id());
/*
$roles = $user->getRoles();
$validRole = false;
foreach ($roles as $role)
}
//user role validation
//$user = \Drupal\user\Entity\User::load($user->id());
/*
$roles = $user->getRoles();
$validRole = false;
foreach ($roles as $role)
if ($role === "ministry") {
$validRole = true;
break;
}
if (!$validRole) {
if (!$validRole) {
return $this->respondWithStatus([
'message' => t("User Invalid Role"),
], Response::HTTP_FORBIDDEN);
}
*/
session_unset();
session_destroy();
}
*/
$response = new Response();
$response->setContent('logout successful');
$response->setStatusCode(Response::HTTP_OK);
$response->headers->set('Content-Type', 'application/json');
return $response;
session_unset();
session_destroy();
return $this->respondWithStatus([
'message' => 'logout successful',
], Response::HTTP_OK);
} //end try
catch (\Exception $e) {
$this->logger->warning($e->getMessage());
$response = new Response();
$response->setContent('forbidden');
$response->setStatusCode(Response::HTTP_FORBIDDEN);
$response->headers->set('Content-Type', 'application/json');
return $response;
return $this->respondWithStatus([
'message' => t("forbidden"),
], Response::HTTP_FORBIDDEN);
}
}
private function respondWithStatus($arr, $s) {
$res = new JsonResponse($arr);
$res->setStatusCode($s);
return $res;
private function respondWithStatus($arr, $s)
{
return (new JsonResponse($arr))
->setStatusCode($s);
}
}
......@@ -1138,6 +1138,46 @@ class EpalStudent extends ContentEntityBase implements EpalStudentInterface
->setDisplayConfigurable('form', true)
->setDisplayConfigurable('view', true);
$fields['lastschool_unittypeid'] = BaseFieldDefinition::create('integer')
->setLabel(t('Τύπος τελευταίου σχολείου'))
->setDescription(t('Τύπος τελευταίου σχολείου'))
->setSettings(array(
'max_length' => 3,
'text_processing' => 0,
))
->setRequired(true)
->setDisplayOptions('view', array(
'label' => 'above',
'type' => 'string',
'weight' => -4,
))
->setDisplayOptions('form', array(
'type' => 'integer',
'weight' => -4,
))
->setDisplayConfigurable('form', true)
->setDisplayConfigurable('view', true);
$fields['lastschool_schoolname'] = BaseFieldDefinition::create('string')
->setLabel(t('Ονομασία τελευταίου σχολείου'))
->setDescription(t('Ονομασία τελευταίου σχολείου'))
->setSettings(array(
'max_length' => 200,
'text_processing' => 0,
))
->setRequired(true)
->setDisplayOptions('view', array(
'label' => 'above',
'type' => 'string',
'weight' => -4,
))
->setDisplayOptions('form', array(
'type' => 'string_textfield',
'weight' => -4,
))
->setDisplayConfigurable('form', true)
->setDisplayConfigurable('view', true);
$fields['lastschool_schoolyear'] = BaseFieldDefinition::create('string')
->setLabel(t('Σχολικό έτος φοίτησης τελευταίου σχολείου'))
->setDescription(t('Σχολικό έτος φοίτησης τελευταίου σχολείου'))
......
......@@ -145,10 +145,10 @@ class OAuthLogout extends ControllerBase
$this->oauthostSession->delete();
$this->logger->info("OAUTH remote logout success for [{$username}]");
$response = new Response();
$response->setContent("{\"message\": \"Server logout successful\",\"next\": \"{$this->redirect_url}\"}");
$response->setStatusCode(Response::HTTP_OK);
$response->headers->set('Content-Type', 'application/json');
$response = (new JsonResponse([
"message" => "Server logout successful",
"next" => "{$this->redirect_url}"
]))->setStatusCode(Response::HTTP_OK);
return $response;
} catch (Exception $e) {
......
......@@ -7,6 +7,7 @@ import { NgReduxModule, DevToolsExtension, NgRedux } from 'ng2-redux';
import {BrowserModule} from '@angular/platform-browser';
import { CookieModule } from 'ngx-cookie';
import { MyDatePickerModule } from 'mydatepicker';
import { NguiAutoCompleteModule } from '@ngui/auto-complete';
import {
FormsModule,
ReactiveFormsModule,
......@@ -22,7 +23,6 @@ import {
} from '@angular/common';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import Main from './containers/main';
import { APP_ROUTER_PROVIDERS, APP_DECLARATIONS } from './app.routes';
......@@ -60,6 +60,7 @@ class MyLocalization extends NgLocalization {
BrowserModule,
MyDatePickerModule,
FormsModule,
NguiAutoCompleteModule,
RouterModule,
ReactiveFormsModule,
APP_ROUTER_PROVIDERS,
......
......@@ -9,6 +9,10 @@ import { IAppState } from '../../store/store';
import {Router, ActivatedRoute, Params} from '@angular/router';
import { BehaviorSubject, Subscription } from 'rxjs/Rx';
import { ILoginInfo } from '../../store/logininfo/logininfo.types';
import { VALID_CAPACITY_PATTERN} from '../../constants';
import {maxValue} from '../../constants';
import {minValue} from '../../constants';
import {
FormBuilder,
......@@ -48,7 +52,17 @@ import {
<p style="margin-top: 20px; line-height: 2em;"> Αλλάξτε παρακαλώ τον αριθμό των τμημάτων που μπορείτε να δημιουργήσετε στο σχολείο σας και πατήστε <i>Αποθήκευση</i>.</p>
<input type="number" formControlName="capacity" min="1" max="10">
<input type="number" formControlName="capacity" min="1" max="10" ng-min="1" ng-max="99" >
<div class="alert alert-danger" *ngIf="formGroup.get('capacity').touched && formGroup.get('capacity').hasError('maxValue')">
Παρακαλώ συμπληρώστε ένα μικρότερο αριθμό!
</div>
<div class="alert alert-danger" *ngIf="formGroup.get('capacity').touched && formGroup.get('capacity').hasError('minValue')">
Παρακαλώ συμπληρώστε ένα μεγαλύτερο αριθμό!
</div>
<div class="alert alert-danger" *ngIf="formGroup.get('capacity').touched && formGroup.get('capacity').hasError('required')">
Συμπληρώστε την διαθεσιμότητα σας σε τμήματα !
</div>
<button type="button" class="btn-primary btn-sm pull-right" (click) ="saveCapacity()">
Αποθήκευση
......@@ -148,11 +162,15 @@ import {
tomeas: ['', []],
taxi: ['', []],
specialit: ['', []],
capacity: ['', []],
capacity: ['', [Validators.pattern(VALID_CAPACITY_PATTERN),Validators.required, maxValue(99), minValue(1)]],
});
}
public showModal(popupMsgId):void {
console.log("about to show modal");
//(<any>$('#distributionWaitingNotice')).modal('show');
......@@ -325,8 +343,6 @@ import {
}
saveCapacity() {
var taxi = +this.formGroup.value.taxi;
......@@ -336,7 +352,9 @@ import {
if ((taxi === 2 && tomeas === 0) || (taxi === 3 && tomeas === 0 ) || (taxi ===3 && specialit === 0 )
|| (taxi === 4 && tomeas === 0 ) || (taxi ===4 && specialit === 0 ) || (taxi = 0) || (capc ===0))
|| (taxi === 4 && tomeas === 0 ) || (taxi ===4 && specialit === 0 ) || (taxi = 0) || (this.formGroup.invalid)
)
{
this.showModal("#checksaved");
} else
......
......@@ -19,13 +19,16 @@ import {
@Component({
selector: 'eduadmin-view',
template: `
<h3> Αριθμός Μαθητών ανα τμήμα σχολείου </h3>
<h4> Αριθμός Μαθητών ανα τμήμα σχολείου!!! </h4>
<div class = "loading" *ngIf="(SchoolsPerPerf$ | async).size === 0">
</div>
<ul class="list-group main-view">
<div *ngFor="let SchoolNames$ of SchoolsPerPerf$ | async; let i=index; let isOdd=odd; let isEven=even" >
<li class="list-group-item isclickable" (click)="setActiveRegion(SchoolNames$.id)" [class.changelistcolor]= "SchoolNames$.status === false" [class.oddout]="isOdd" [class.evenout]="isEven" [class.selectedout]="regionActive === SchoolNames$.id" >
<h5> {{SchoolNames$.name}}</h5>
</li>
<div class = "loading" *ngIf="(CoursesPerPerf$ | async).size === 0">
</div>
<div *ngFor="let CoursesNames$ of CoursesPerPerf$ | async; let j=index; let isOdd2=odd; let isEven2=even" [class.oddin]="isOdd2" [class.evenin]="isEven2" [class.changecolor]="calccolor(CoursesNames$.size,CoursesNames$.limitdown)" [hidden]="SchoolNames$.id !== regionActive" >
<div> {{CoursesNames$.name}}</div> <div class= "aastyle"><strong>Αριθμός Μαθητών:</strong>{{CoursesNames$.size}} </div>
......
import {Router, ActivatedRoute, Params} from '@angular/router';
import {OnInit, OnDestroy, Component} from '@angular/core';
import { LoginInfoActions } from '../actions/logininfo.actions';
import { ILoginInfo } from '../store/logininfo/logininfo.types';
import { LOGININFO_INITIAL_STATE } from '../store/logininfo/logininfo.initial-state';
import { NgRedux, select } from 'ng2-redux';
import { BehaviorSubject, Subscription } from 'rxjs/Rx';
import { IAppState } from '../store/store';
import { HelperDataService } from '../services/helper-data-service';
import { CookieService } from 'ngx-cookie';
import {
FormBuilder,
FormGroup,
FormControl,
FormArray
} from '@angular/forms';
import { Router, ActivatedRoute, Params } from "@angular/router";
import { OnInit, OnDestroy, Component } from "@angular/core";
import { LoginInfoActions } from "../actions/logininfo.actions";
import { ILoginInfo } from "../store/logininfo/logininfo.types";
import { LOGININFO_INITIAL_STATE } from "../store/logininfo/logininfo.initial-state";
import { NgRedux, select } from "ng2-redux";
import { BehaviorSubject, Subscription } from "rxjs/Rx";
import { IAppState } from "../store/store";
import { HelperDataService } from "../services/helper-data-service";
import { CookieService } from "ngx-cookie";
import { FormBuilder, FormGroup, FormControl, FormArray } from "@angular/forms";
import { API_ENDPOINT, API_ENDPOINT_PARAMS } from "../app.settings";
import { API_ENDPOINT, API_ENDPOINT_PARAMS } from '../app.settings';
@Component({
selector: 'school-home',
selector: "school-home",
template: `
<div>
<form [formGroup]="formGroup" method = "POST" action="{{apiEndPoint}}/cas/login{{apiEndPointParams}}" #form>
<!-- <input type="hidden" name="X-oauth-enabled" value="true"> -->
<div *ngFor="let loginInfoToken$ of loginInfo$ | async; let i=index"></div>