[DEV] many update and corect securityu fail n set parameters
This commit is contained in:
parent
e1bb3a3ab9
commit
dd936c2e94
@ -27,7 +27,7 @@
|
||||
<dependency>
|
||||
<groupId>kangaroo-and-rabbit</groupId>
|
||||
<artifactId>archidata</artifactId>
|
||||
<version>0.3.1</version>
|
||||
<version>0.3.2</version>
|
||||
</dependency>
|
||||
<!-- testing -->
|
||||
<dependency>
|
||||
|
@ -11,8 +11,8 @@ public class WebLauncherLocal {
|
||||
// for local test:
|
||||
ConfigBaseVariable.apiAdress = "http://0.0.0.0:15080/karso/api/";
|
||||
ConfigBaseVariable.dbPort = "3306";
|
||||
ConfigBaseVariable.dbType = "sqlite";
|
||||
ConfigBaseVariable.dbHost = "./bdd_base.sqlite";
|
||||
//ConfigBaseVariable.dbType = "sqlite";
|
||||
//ConfigBaseVariable.dbHost = "./bdd_base.sqlite";
|
||||
|
||||
}
|
||||
WebLauncher.main(args);
|
||||
|
@ -72,7 +72,7 @@ public class SystemConfigResource {
|
||||
}
|
||||
@PUT
|
||||
@Path("key/{key}")
|
||||
@RolesAllowed(value= {"USER", "ADMIN"})
|
||||
@RolesAllowed(value= {"ADMIN"})
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Response setKey(@Context SecurityContext sc, @PathParam("key") String key, String jsonRequest) throws Exception {
|
||||
Settings res = null;
|
||||
@ -90,7 +90,7 @@ public class SystemConfigResource {
|
||||
JsonNode value = root.findPath("value");
|
||||
|
||||
res.value = value.asText();
|
||||
|
||||
System.out.println(" update valu : " + res.value);
|
||||
SqlWrapper.update(res, res.id, List.of("value"));
|
||||
return Response.status(201).entity("{ \"value\":\"" + res.value + "\"}").build();
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ import {
|
||||
UserService,
|
||||
} from 'common/service';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { ErrorComponent, PopInComponent, SpinerComponent, TopMenuComponent, UploadFileComponent, PasswordEntryComponent, EntryComponent, AsyncActionStatusComponent, ErrorMessageStateComponent, CheckboxComponent, BurgerPropertyComponent, EntryValidatorComponent, RenderSettingsComponent, RenderFormComponent } from 'common/component';
|
||||
import { ErrorComponent, PopInComponent, SpinerComponent, TopMenuComponent, UploadFileComponent, PasswordEntryComponent, EntryComponent, AsyncActionStatusComponent, ErrorMessageStateComponent, CheckboxComponent, BurgerPropertyComponent, EntryValidatorComponent, RenderSettingsComponent, RenderFormComponent, EntryNumberComponent } from 'common/component';
|
||||
import { ForbiddenScene } from 'common/scene';
|
||||
import { AdminUserService, ApplicationService, ApplicationTokenService, SettingsService } from 'app/service';
|
||||
import { PopInUploadProgress, PopInDeleteConfirm } from 'common/popin';
|
||||
@ -63,6 +63,7 @@ import { PopInUploadProgress, PopInDeleteConfirm } from 'common/popin';
|
||||
BurgerPropertyComponent,
|
||||
RenderSettingsComponent,
|
||||
RenderFormComponent,
|
||||
EntryNumberComponent,
|
||||
|
||||
PopInComponent,
|
||||
PopInUploadProgress,
|
||||
|
@ -5,72 +5,19 @@
|
||||
<name>Application properties</name>
|
||||
<description>Update property of the application:</description>
|
||||
<body>
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td width="25%"><b>id:</b></td>
|
||||
<td width="75%">{{application?.id}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Name:</b></td>
|
||||
<td>
|
||||
<app-entry
|
||||
[value]="application?.name"
|
||||
placeholder="Enter application name"
|
||||
[hasError]="nameState !== true"
|
||||
(changeValue)="checkName($event)"></app-entry>
|
||||
<app-error-message-state [value]="nameState"></app-error-message-state>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Description:</b></td>
|
||||
<td>
|
||||
<app-entry
|
||||
[value]="application?.description"
|
||||
(changeValue)="updateDescription($event)"></app-entry>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Redirect (http://):</b></td>
|
||||
<td>
|
||||
<app-entry
|
||||
[value]="application?.redirect"
|
||||
placeholder="Enter http redirect adresses "
|
||||
[hasError]="redirectState !== true"
|
||||
(changeValue)="checkRedirect($event)"></app-entry>
|
||||
<app-error-message-state [value]="redirectState"></app-error-message-state>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Redirect development (http://):</b></td>
|
||||
<td>
|
||||
<app-entry
|
||||
[value]="application?.redirectDev"
|
||||
(changeValue)="updateRedirectDev($event)"></app-entry>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Notification address (http://):</b></td>
|
||||
<td>
|
||||
<app-entry
|
||||
[value]="application?.notification"
|
||||
(changeValue)="updateNotification($event)"></app-entry>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>TTL (seconds before expiration):</b></td>
|
||||
<td>
|
||||
<app-entry
|
||||
[value]="application?.ttl"
|
||||
(changeValue)="updateTTL($event)"></app-entry>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<spiner *ngIf="editApplicationMenu===undefined"></spiner>
|
||||
<app-render-form
|
||||
*ngIf="editApplicationMenu!==undefined"
|
||||
[values]="editApplicationMenu"
|
||||
(deltaValues)="onEditValues($event)"
|
||||
(changeState)="onEditState($event)"
|
||||
></app-render-form>
|
||||
</body>
|
||||
<footer>
|
||||
<button
|
||||
class="button login color-button-validate color-shadow-black"
|
||||
id="create-button"
|
||||
[disabled]="validateButtonCreateApplicationDisabled"
|
||||
[disabled]="updateButtonDisabled !== 0"
|
||||
(click)="onUpdateApplication()"
|
||||
type="submit">
|
||||
Update
|
||||
@ -108,41 +55,28 @@
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</burger-property>
|
||||
</div>
|
||||
<div class="clear"><br/></div>
|
||||
<div style="padding-top:15px;">
|
||||
<burger-property>
|
||||
<name>Add Token</name>
|
||||
<body>
|
||||
<app-render-form
|
||||
[values]="createTokenMenu"
|
||||
(deltaValues)="onCreateValueDeltaValues($event)"
|
||||
(changeState)="onCreateValueState($event)"
|
||||
></app-render-form>
|
||||
</body>
|
||||
<footer>
|
||||
<table>
|
||||
<tr>
|
||||
<td width="25%">Name/Descriptiion token:</td>
|
||||
<td>
|
||||
<app-entry-validator
|
||||
[value]="tokenName"
|
||||
placeholder="Enter the token name / decription"
|
||||
(checker)="checkTokenName($event)"
|
||||
(changeValue)="newTokenName($event)"></app-entry-validator>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Validity time (in day)</td>
|
||||
<td>
|
||||
<app-entry-validator
|
||||
[value]="tokenTTL"
|
||||
placeholder="Enter the Time To Lead (in day)"
|
||||
(checker)="checkTokenTTL($event)"
|
||||
(changeValue)="newTokenTTL($event)"></app-entry-validator>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button
|
||||
class="button login color-button-validate color-shadow-black"
|
||||
id="create-button"
|
||||
(click)="createToken()"
|
||||
type="submit">
|
||||
+ Create new Token
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button
|
||||
class="button login color-button-validate color-shadow-black"
|
||||
id="create-button"
|
||||
(click)="createToken()"
|
||||
[disabled]="createTokenDisabled !== 0"
|
||||
type="submit">
|
||||
+ Create new Token
|
||||
</button>
|
||||
</footer>
|
||||
</burger-property>
|
||||
</div>
|
||||
|
@ -9,9 +9,9 @@ import { ActivatedRoute } from '@angular/router';
|
||||
import { ApplicationService, ApplicationModel, ApplicationTokenService } from 'app/service';
|
||||
import { ApplicationTokenModel } from 'app/service/application-token';
|
||||
import { AsyncActionState } from 'common/component';
|
||||
import { CheckerParameter } from 'common/component/entry-validator/entry-validator';
|
||||
import { CheckerParameterType, SettingsItem, SettingType } from 'common/component/render-settings/render-settings';
|
||||
import { NotificationService, PopInService } from 'common/service';
|
||||
import { isNumeric } from 'common/utils';
|
||||
import { isNumber, isNumeric, isString } from 'common/utils';
|
||||
|
||||
@Component({
|
||||
selector: 'application-setting-edit',
|
||||
@ -42,9 +42,9 @@ export class ApplicationEditScene implements OnInit {
|
||||
.then((response: ApplicationModel) => {
|
||||
console.log(`??? get full response: ${JSON.stringify(response, null, 4)}`);
|
||||
self.application = response;
|
||||
self.applicationRef = { ...response };
|
||||
self.checkName(self.application.name);
|
||||
self.checkRedirect(self.application.redirect);
|
||||
//self.checkRedirect(self.application.redirect);
|
||||
this.configureEditInput();
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.log(`??? get ERROR response: ${JSON.stringify(error, null, 4)}`);
|
||||
@ -58,133 +58,143 @@ export class ApplicationEditScene implements OnInit {
|
||||
.catch((error: any) => {
|
||||
console.log(`??? get ERROR response: ${JSON.stringify(error, null, 4)}`);
|
||||
});
|
||||
this.configureInput();
|
||||
}
|
||||
|
||||
formatTimestamp(unix_timestamp: number) {
|
||||
return new Date(unix_timestamp).toISOString().replace("T", " ").replace("Z", " GMT").replace(".000", "");
|
||||
}
|
||||
|
||||
updateDescription(newValue: string): void {
|
||||
this.application.description = newValue;
|
||||
this.updateButtonVisibility();
|
||||
}
|
||||
updateRedirectDev(newValue: string): void {
|
||||
this.application.redirectDev = newValue;
|
||||
this.updateButtonVisibility();
|
||||
}
|
||||
updateNotification(newValue: string): void {
|
||||
this.application.notification = newValue;
|
||||
this.updateButtonVisibility();
|
||||
}
|
||||
updateTTL(newValue: string): void {
|
||||
if (isNumeric(newValue)) {
|
||||
this.application.ttl = Number(newValue);
|
||||
}
|
||||
this.updateButtonVisibility();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public nameState: boolean|string = false;
|
||||
public redirectState: boolean|string = false;
|
||||
public validateButtonCreateApplicationDisabled: boolean = true;
|
||||
/**
|
||||
* update the state of the validation button. if all is OK, the button will became clickable
|
||||
*/
|
||||
updateButtonVisibility(): void {
|
||||
if ( ! (this.nameState === true && this.redirectState === true ) ) {
|
||||
this.validateButtonCreateApplicationDisabled = true;
|
||||
return;
|
||||
}
|
||||
if (this.application.name !== this.applicationRef.name) {
|
||||
this.validateButtonCreateApplicationDisabled = false;
|
||||
return;
|
||||
}
|
||||
if (this.application.description !== this.applicationRef.description) {
|
||||
this.validateButtonCreateApplicationDisabled = false;
|
||||
return;
|
||||
}
|
||||
if (this.application.redirect !== this.applicationRef.redirect) {
|
||||
this.validateButtonCreateApplicationDisabled = false;
|
||||
return;
|
||||
}
|
||||
if (this.application.redirectDev !== this.applicationRef.redirectDev) {
|
||||
this.validateButtonCreateApplicationDisabled = false;
|
||||
return;
|
||||
}
|
||||
if (this.application.notification !== this.applicationRef.notification) {
|
||||
this.validateButtonCreateApplicationDisabled = false;
|
||||
return;
|
||||
}
|
||||
if (this.application.ttl !== this.applicationRef.ttl) {
|
||||
this.validateButtonCreateApplicationDisabled = false;
|
||||
return;
|
||||
}
|
||||
this.validateButtonCreateApplicationDisabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the login writing rules
|
||||
*/
|
||||
checkName(newValue: string): void {
|
||||
this.application.name = newValue;
|
||||
if (this.application?.name?.length < 6) {
|
||||
this.nameState = "This name is too small >=6.";
|
||||
}
|
||||
this.nameState = true;
|
||||
this.updateButtonVisibility();
|
||||
editApplicationMenu: SettingsItem[] = undefined;
|
||||
|
||||
// this permit to clear the input menu...
|
||||
configureEditInput() {
|
||||
this.editApplicationMenu = [
|
||||
{
|
||||
type: SettingType.VALUE,
|
||||
title: 'ID:',
|
||||
value: this.application?.id,
|
||||
},
|
||||
{
|
||||
type: SettingType.STRING,
|
||||
title: 'Name:',
|
||||
placeholder: 'Enter application name',
|
||||
key: 'name',
|
||||
value: this.application?.name,
|
||||
checker: (value) => { return this.checkName(value)},
|
||||
require: true,
|
||||
},
|
||||
{
|
||||
type: SettingType.STRING,
|
||||
title: 'Description:',
|
||||
key: 'description',
|
||||
value: this.application?.description,
|
||||
},
|
||||
{
|
||||
type: SettingType.STRING,
|
||||
title: 'Redirect:',
|
||||
description:"Redirect when login (http://):",
|
||||
placeholder: 'Enter http redirect adresses',
|
||||
key: 'redirect',
|
||||
value: this.application?.redirect,
|
||||
checker: (value: CheckerParameterType) => { return this.checkRedirect(value)},
|
||||
require: true,
|
||||
},
|
||||
{
|
||||
type: SettingType.STRING,
|
||||
title: 'Redirect (dev):',
|
||||
description:"Redirect development (http://):",
|
||||
placeholder: 'Enter http redirect adresses',
|
||||
key: 'redirectDev',
|
||||
value: this.application?.redirectDev,
|
||||
},
|
||||
{
|
||||
type: SettingType.STRING,
|
||||
title: 'Notification:',
|
||||
description:"Redirect development (http://):",
|
||||
placeholder:"http://xxx/sso-event",
|
||||
key: 'notification',
|
||||
value: this.application?.notification,
|
||||
},
|
||||
{
|
||||
type: SettingType.NUMBER,
|
||||
title: 'TTL:',
|
||||
description: 'Time in seconds of the validity of the token',
|
||||
placeholder: "888",
|
||||
key: 'ttl',
|
||||
value: this.application?.ttl,
|
||||
checker: (value: CheckerParameterType) => { return this.checkTTL(value)},
|
||||
require: true,
|
||||
},
|
||||
];
|
||||
this.updateButtonDisabled = undefined;
|
||||
this.dataUpdate = {};
|
||||
}
|
||||
/**
|
||||
* Check the login writing rules
|
||||
* Check the redirection have a good form
|
||||
*/
|
||||
checkRedirect(newValue: string): void {
|
||||
this.application.redirect = newValue;
|
||||
this.redirectState = true;
|
||||
if (this.application?.redirect?.length <= 5) {
|
||||
this.redirectState = "This redirect is too small.";
|
||||
checkRedirect(value: CheckerParameterType): string | undefined {
|
||||
if (!isString(value)) {
|
||||
return "must be a string";
|
||||
}
|
||||
this.updateButtonVisibility();
|
||||
if (value.length <= 5) {
|
||||
return "This redirect is too small.";
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
updateButtonDisabled: number | undefined = undefined;
|
||||
dataUpdate: object = {}
|
||||
|
||||
onEditState(value: number) {
|
||||
console.log(`changeState : ${JSON.stringify(value, null, 2)}`);
|
||||
this.updateButtonDisabled = value;
|
||||
// we do not change the main ref ==> notify angular that something have change and need to be re-render???
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
onEditValues(value: any) {
|
||||
console.log(`onDeltaValues : ${JSON.stringify(value, null, 2)}`);
|
||||
this.dataUpdate = value;
|
||||
// we do not change the main ref ==> notify angular that something have change and need to be re-render???
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
|
||||
createState: string | boolean = undefined;
|
||||
|
||||
|
||||
|
||||
updateState: string | boolean = undefined;
|
||||
/**
|
||||
* Request the creation of a new application.
|
||||
*/
|
||||
onUpdateApplication(): void {
|
||||
console.log(`create user:`);
|
||||
this.createState = AsyncActionState.LOADING;
|
||||
this.updateState = AsyncActionState.LOADING;
|
||||
let self = this;
|
||||
/*
|
||||
this.applicationService.create(this.name, this.redirect)
|
||||
this.applicationService.update(this.id, this.dataUpdate)
|
||||
.then(
|
||||
(data: ApplicationModel) => {
|
||||
self.createState = AsyncActionState.DONE;
|
||||
console.log(`Get new user: ${JSON.stringify(data, null, 2)}`);
|
||||
////////self.applications.push(data);
|
||||
self.cdr.detectChanges();
|
||||
self.name = null;
|
||||
self.redirect = null;
|
||||
self.updateState = AsyncActionState.DONE;
|
||||
console.log(`Get new application data: ${JSON.stringify(data, null, 2)}`);
|
||||
self.application = data;
|
||||
self.configureEditInput()
|
||||
setTimeout(() => {
|
||||
this.createState = undefined;
|
||||
this.updateState = undefined;
|
||||
}, 3000);
|
||||
}
|
||||
).catch(
|
||||
(error: any) => {
|
||||
self.createState = AsyncActionState.FAIL;
|
||||
self.updateState = AsyncActionState.FAIL;
|
||||
setTimeout(() => {
|
||||
self.createState = undefined;
|
||||
self.updateState = undefined;
|
||||
}, 3000);
|
||||
}
|
||||
);
|
||||
*/
|
||||
}
|
||||
|
||||
createToken(): void {
|
||||
let self = this;
|
||||
this.applicationTokenService
|
||||
.create(this.id, this.tokenName, this.tokenTTL)
|
||||
.create(this.id, this.dataCreateApplication["name"], this.dataCreateApplication["ttl"])
|
||||
.then((response: ApplicationTokenModel) => {
|
||||
console.log(`??? get fullllllll response: ${JSON.stringify(response, null, 4)}`);
|
||||
//console.log(`??? get fullllllll response: ${JSON.stringify(response, null, 4)}`);
|
||||
self.tokens.push(response);
|
||||
response.token = `"${response.id}:${response.token}"`
|
||||
self.cdr.detectChanges();
|
||||
@ -228,64 +238,75 @@ export class ApplicationEditScene implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
createFrom = [
|
||||
{
|
||||
title: "Name/Description token",
|
||||
placeholder: "Enter the token name / decription",
|
||||
value: "",
|
||||
type: "INPUT",
|
||||
checker: this.checkTokenName,
|
||||
},
|
||||
{
|
||||
title: "Validity time (in day)",
|
||||
placeholder: "Enter the Time To Lead (in day)",
|
||||
value: "",
|
||||
checker: this.checkTokenName,
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
|
||||
tokenName: string = undefined;
|
||||
tokenTTL: number = undefined;
|
||||
tokenCreateErrorCount: number = 2;
|
||||
|
||||
newTokenName(newValue: string) {
|
||||
this.tokenName = newValue;
|
||||
|
||||
}
|
||||
checkTokenName(chekParam: CheckerParameter): void {
|
||||
if (chekParam.value.length < 3) {
|
||||
chekParam.result("Must have 3 chars");
|
||||
return;
|
||||
}
|
||||
chekParam.result(true);
|
||||
}
|
||||
createTokenMenu: SettingsItem[] = []
|
||||
|
||||
newTokenTTL(newValue: string) {
|
||||
if (isNumeric(newValue)) {
|
||||
this.tokenTTL = Number(newValue);
|
||||
}
|
||||
// this permit to clear the input menu...
|
||||
configureInput() {
|
||||
this.createTokenMenu = [
|
||||
{
|
||||
type: SettingType.STRING,
|
||||
title: 'Token name:',
|
||||
placeholder: 'Enter the token name / decription',
|
||||
key: 'name',
|
||||
value: '',
|
||||
checker: (value: CheckerParameterType) => { return this.checkName(value)},
|
||||
require: true,
|
||||
},
|
||||
{
|
||||
type: SettingType.NUMBER,
|
||||
title: 'Token TTL:',
|
||||
placeholder: 'Enter the Time To Lead (in day)',
|
||||
key: 'ttl',
|
||||
value: '',
|
||||
checker: (value: CheckerParameterType) => { return this.checkTTL(value)},
|
||||
require: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
checkTokenTTL(chekParam: CheckerParameter): void {
|
||||
if (!isNumeric(chekParam.value)) {
|
||||
chekParam.result("Must be a number");
|
||||
return;
|
||||
public createTokenDisabled: number = undefined;
|
||||
public dataCreateApplication: object = {};
|
||||
|
||||
/**
|
||||
* Check the application name is available
|
||||
*/
|
||||
checkName(value: CheckerParameterType): string | undefined {
|
||||
if (!isString(value)) {
|
||||
return "Must be a String";
|
||||
}
|
||||
if (chekParam.value.length<1) {
|
||||
chekParam.result("Minimum one day");
|
||||
return;
|
||||
if (value.length < 3) {
|
||||
return "This name is too small >=3.";
|
||||
}
|
||||
let value = Number(chekParam.value);
|
||||
if (value<0) {
|
||||
chekParam.result("Value must be > 0");
|
||||
return;
|
||||
}
|
||||
if (value===0) {
|
||||
chekParam.result("This have no need to create token");
|
||||
return;
|
||||
}
|
||||
chekParam.result(true);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the redirection have a good form
|
||||
*/
|
||||
checkTTL(value: CheckerParameterType): string | undefined {
|
||||
if (!isNumber(value)) {
|
||||
return "Must be a number";
|
||||
}
|
||||
const tokenTTL = Number(value);
|
||||
if (tokenTTL < 1) {
|
||||
return "Minimum one day";
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
onCreateValueState(value: number) {
|
||||
console.log(`changeState : ${JSON.stringify(value, null, 2)}`);
|
||||
this.createTokenDisabled = value;
|
||||
// we do not change the main ref ==> notify angular that something have change and need to be re-render???
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
onCreateValueDeltaValues(value: any) {
|
||||
console.log(`onDeltaValues : ${JSON.stringify(value, null, 2)}`);
|
||||
this.dataCreateApplication = value;
|
||||
// we do not change the main ref ==> notify angular that something have change and need to be re-render???
|
||||
this.cdr.detectChanges();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
<th>name</th>
|
||||
<th>Description</th>
|
||||
<th>redirect</th>
|
||||
<th>TTL</th>
|
||||
<th>TTL (min)</th>
|
||||
<th>Notification</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
|
@ -8,8 +8,9 @@ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@
|
||||
import { Router } from '@angular/router';
|
||||
import { ApplicationService, ApplicationModel } from 'app/service';
|
||||
import { AsyncActionState } from 'common/component';
|
||||
import { SettingsItem, SettingType } from 'common/component/render-settings/render-settings';
|
||||
import { CheckerParameterType, SettingsItem, SettingType } from 'common/component/render-settings/render-settings';
|
||||
import { NotificationService, PopInService } from 'common/service';
|
||||
import { isString } from 'common/utils';
|
||||
|
||||
@Component({
|
||||
selector: 'application-setting',
|
||||
@ -113,7 +114,10 @@ export class ApplicationsScene implements OnInit {
|
||||
/**
|
||||
* Check the application name is available
|
||||
*/
|
||||
checkName(value: string): string | undefined {
|
||||
checkName(value: CheckerParameterType): string | undefined {
|
||||
if (!isString(value)) {
|
||||
return "must be a string";
|
||||
}
|
||||
console.log(`input value : ${value}`)
|
||||
if (value.length < 6) {
|
||||
return "This name is too small >=6.";
|
||||
@ -130,7 +134,10 @@ export class ApplicationsScene implements OnInit {
|
||||
/**
|
||||
* Check the redirection have a good form
|
||||
*/
|
||||
checkRedirect(value: string): string | undefined {
|
||||
checkRedirect(value: CheckerParameterType): string | undefined {
|
||||
if (!isString(value)) {
|
||||
return "must be a string";
|
||||
}
|
||||
if (value.length <= 5) {
|
||||
return "This redirect is too small.";
|
||||
}
|
||||
|
@ -5,7 +5,9 @@
|
||||
<name>{{data.title}}</name>
|
||||
<description>{{data.description}}</description>
|
||||
<body>
|
||||
<spiner *ngIf="data.values===undefined"></spiner>
|
||||
<app-render-settings
|
||||
*ngIf="data.values!==undefined"
|
||||
[values]="data.values"
|
||||
(deltaValues)="onDeltaValues($event, data)"
|
||||
(changeState)="onState($event, data)"
|
||||
|
@ -9,16 +9,11 @@ import { ActivatedRoute } from '@angular/router';
|
||||
import { SettingsService } from 'app/service';
|
||||
import { isSettingsItem, SettingsItem, SettingType } from 'common/component/render-settings/render-settings';
|
||||
import {
|
||||
isArrayOf,
|
||||
isBoolean,
|
||||
isInArray,
|
||||
isNullOrUndefined,
|
||||
isNumber,
|
||||
isObject,
|
||||
isOptionalArrayOf,
|
||||
isOptionalOf,
|
||||
isString,
|
||||
isUndefined,
|
||||
} from 'common/utils';
|
||||
|
||||
|
||||
@ -35,6 +30,8 @@ export interface SettingsItem222 {
|
||||
newValues?: object;
|
||||
// local state: if undefined => no change, otherwise the number of wrong values.
|
||||
state?: number;
|
||||
// values get from the server.
|
||||
serverValues?: object;
|
||||
}
|
||||
|
||||
export function isSettingsItem222(data: any): data is SettingsItem222 {
|
||||
@ -75,47 +72,58 @@ export class SettingsScene implements OnInit {
|
||||
{
|
||||
title: 'Authentication:',
|
||||
description: 'Manage the right of access to the web-services',
|
||||
values: [
|
||||
{
|
||||
type: SettingType.BOOLEAN,
|
||||
title: 'Enable Sign-in',
|
||||
description: 'Enable User to sign-in (only authorize administrators).',
|
||||
key: 'SIGN_IN_ENABLE',
|
||||
value: true,
|
||||
},
|
||||
{
|
||||
type: SettingType.LINE,
|
||||
},
|
||||
{
|
||||
type: SettingType.BOOLEAN,
|
||||
title: 'Enable Sign-up',
|
||||
description: 'Enable unregister user to sign-up (register) on this web-site.',
|
||||
key: 'SIGN_UP_ENABLE',
|
||||
value: false,
|
||||
},
|
||||
{
|
||||
type: SettingType.STRING,
|
||||
title: 'Sign-up e-mail filter',
|
||||
description: 'Specify the e-mail filtering to sign-up (regex).',
|
||||
key: 'SIGN_UP_FILTER',
|
||||
value: '^.*$',
|
||||
},
|
||||
{
|
||||
type: SettingType.BOOLEAN,
|
||||
title: 'e-mail validation required',
|
||||
description: 'Force-user to validate his e-mail to access on service.',
|
||||
key: 'EMAIL_VALIDATION_REQUIRED',
|
||||
value: false,
|
||||
},
|
||||
],
|
||||
values: undefined,
|
||||
},
|
||||
];
|
||||
|
||||
// this permit to clear the input menu...
|
||||
|
||||
configureEditInput() {
|
||||
const root = this.menu[0];
|
||||
root.values = [
|
||||
{
|
||||
type: SettingType.BOOLEAN,
|
||||
title: 'Enable Sign-in',
|
||||
description: 'Enable User to sign-in (only authorize administrators).',
|
||||
key: 'SIGN_IN_ENABLE',
|
||||
value: root.serverValues["SIGN_IN_ENABLE"],
|
||||
},
|
||||
{
|
||||
type: SettingType.LINE,
|
||||
},
|
||||
{
|
||||
type: SettingType.BOOLEAN,
|
||||
title: 'Enable Sign-up',
|
||||
description: 'Enable unregister user to sign-up (register) on this web-site.',
|
||||
key: 'SIGN_UP_ENABLE',
|
||||
value: root.serverValues["SIGN_UP_ENABLE"],
|
||||
},
|
||||
{
|
||||
type: SettingType.STRING,
|
||||
title: 'Sign-up e-mail filter',
|
||||
description: 'Specify the e-mail filtering to sign-up (regex).',
|
||||
key: 'SIGN_UP_FILTER',
|
||||
value: root.serverValues["SIGN_UP_FILTER"],
|
||||
},
|
||||
{
|
||||
type: SettingType.BOOLEAN,
|
||||
title: 'e-mail validation required',
|
||||
description: 'Force-user to validate his e-mail to access on service.',
|
||||
key: 'EMAIL_VALIDATION_REQUIRED',
|
||||
value: root.serverValues["EMAIL_VALIDATION_REQUIRED"],
|
||||
},
|
||||
],
|
||||
this.menu[0].state = undefined;
|
||||
this.menu[0].newValues = {};
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.settingService
|
||||
.gets(['SIGN_IN_ENABLE', 'SIGN_UP_ENABLE', 'SIGN_UP_FILTER', 'EMAIL_VALIDATION_REQUIRED'])
|
||||
.then((response: object) => {
|
||||
console.log(`??? get full response: ${JSON.stringify(response, null, 4)}`);
|
||||
this.menu[0].serverValues = response;
|
||||
this.configureEditInput();
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.log(`??? get ERROR response: ${JSON.stringify(error, null, 4)}`);
|
||||
@ -165,6 +173,7 @@ export class SettingsScene implements OnInit {
|
||||
onUpdate(elem: SettingsItem222) {
|
||||
this.settingService.sets(elem.newValues)
|
||||
.then((result: object) => {
|
||||
// TODO ...
|
||||
//multipleResponse.add(key, result);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
|
@ -173,6 +173,26 @@ export class ApplicationService {
|
||||
});
|
||||
});
|
||||
}
|
||||
update(id: number, updateState: object): Promise<ApplicationModel> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.http
|
||||
.requestJson({
|
||||
server: 'karso',
|
||||
endPoint: `application/${id}`,
|
||||
requestType: HTTPRequestModel.PUT,
|
||||
accept: HTTPMimeType.JSON,
|
||||
contentType: HTTPMimeType.JSON,
|
||||
body:updateState,
|
||||
})
|
||||
.then((response: ModelResponseHttp) => {
|
||||
// TODO: check type ...
|
||||
resolve(response.data);
|
||||
})
|
||||
.catch((error: any) => {
|
||||
reject(`return ERROR ${JSON.stringify(error, null, 2)}`);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
create(name: string, redirect: string): Promise<ApplicationModel> {
|
||||
let body = {
|
||||
|
15
front/src/common/component/entry-number/entry-number.html
Normal file
15
front/src/common/component/entry-number/entry-number.html
Normal file
@ -0,0 +1,15 @@
|
||||
<div class="top">
|
||||
<input
|
||||
type="text"
|
||||
[placeholder]="placeholder===undefined?'':placeholder"
|
||||
required=""
|
||||
[style.border]="hasError||notANumber? '2px dashed red' : ''"
|
||||
[(ngModel)]="value"
|
||||
(input)="onChangeValue($event.target.value)" />
|
||||
<button class="eye-button-2 unselectable" tabindex="-1" (click)="onDecrement()" type="submit">
|
||||
<i class="material-icons">arrow_back_ios</i>
|
||||
</button>
|
||||
<button class="eye-button unselectable" tabindex="-1" (click)="onIncrement()" type="submit">
|
||||
<i class="material-icons">arrow_forward_ios</i>
|
||||
</button>
|
||||
</div>
|
39
front/src/common/component/entry-number/entry-number.less
Normal file
39
front/src/common/component/entry-number/entry-number.less
Normal file
@ -0,0 +1,39 @@
|
||||
input {
|
||||
width: 100%;
|
||||
padding: 12px 20px;
|
||||
margin: 8px 0;
|
||||
display: inline-block;
|
||||
border: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
z-index: 5;
|
||||
}
|
||||
.eye-button {
|
||||
margin-left: -44px;
|
||||
margin-top: 15px;
|
||||
float: right;
|
||||
position: relative;
|
||||
display: block;
|
||||
border: none;
|
||||
z-index: 15;
|
||||
background: none;
|
||||
padding: 4 1 13 1;
|
||||
:hover {
|
||||
background: none;
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
.eye-button-2 {
|
||||
margin-left: -70px;
|
||||
margin-top: 12px;
|
||||
float: right;
|
||||
position: relative;
|
||||
display: block;
|
||||
border: none;
|
||||
z-index: 15;
|
||||
background: none;
|
||||
padding: 4px 30px 4px 1px;
|
||||
:hover {
|
||||
background: none;
|
||||
color: red;
|
||||
}
|
||||
}
|
70
front/src/common/component/entry-number/entry-number.ts
Normal file
70
front/src/common/component/entry-number/entry-number.ts
Normal file
@ -0,0 +1,70 @@
|
||||
/** @file
|
||||
* @author Edouard DUPIN
|
||||
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||
* @license PROPRIETARY (see license file)
|
||||
*/
|
||||
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
import { isNumeric } from 'common/utils';
|
||||
|
||||
@Component({
|
||||
selector: 'app-entry-number',
|
||||
templateUrl: 'entry-number.html',
|
||||
styleUrls: ['entry-number.less'],
|
||||
})
|
||||
export class EntryNumberComponent implements OnInit {
|
||||
/// Value of the password
|
||||
@Input() value: string|undefined = '';
|
||||
/// Placeholder of the Value
|
||||
@Input() placeholder: string|undefined = '';
|
||||
/// The element has an error
|
||||
@Input() hasError: boolean = false;
|
||||
/// event when change the value of the password
|
||||
@Output() changeValue: EventEmitter<number|undefined> = new EventEmitter();
|
||||
|
||||
public notANumber: boolean = false;
|
||||
ngOnInit(): void {
|
||||
//if (value)
|
||||
}
|
||||
|
||||
/**
|
||||
* When input value change, need update the display and change the internal value.
|
||||
* @param newValue New value set on the password
|
||||
*/
|
||||
onChangeValue(newValue: string): void {
|
||||
if (newValue === "") {
|
||||
this.value = undefined;
|
||||
this.notANumber = false;
|
||||
this.changeValue.emit(undefined);
|
||||
return;
|
||||
}
|
||||
this.value = newValue;
|
||||
this.notANumber = false;
|
||||
if (!isNumeric(this.value)) {
|
||||
this.notANumber = true;
|
||||
}
|
||||
const numValue = Number(this.value);
|
||||
this.changeValue.emit(numValue);
|
||||
}
|
||||
onIncrement() {
|
||||
this.notANumber = false;
|
||||
let newValue = undefined;
|
||||
if (!isNumeric(this.value)) {
|
||||
newValue = 0;
|
||||
} else {
|
||||
newValue = Number(this.value) + 1;
|
||||
}
|
||||
this.value = "" + newValue;
|
||||
this.changeValue.emit(newValue);
|
||||
}
|
||||
onDecrement() {
|
||||
this.notANumber = false;
|
||||
let newValue = undefined;
|
||||
if (!isNumeric(this.value)) {
|
||||
newValue = 0;
|
||||
} else {
|
||||
newValue = Number(this.value) - 1;
|
||||
}
|
||||
this.value = "" + newValue;
|
||||
this.changeValue.emit(newValue);
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
<div class="top">
|
||||
<input
|
||||
type="text"
|
||||
[placeholder]="placeholder"
|
||||
[placeholder]="placeholder===undefined?'':placeholder"
|
||||
required=""
|
||||
[style.border]="hasError? '2px dashed red' : ''"
|
||||
[value]="value===undefined?'':value"
|
||||
|
@ -12,9 +12,9 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
|
||||
})
|
||||
export class EntryComponent implements OnInit {
|
||||
/// Value of the password
|
||||
@Input() value: string = '';
|
||||
@Input() value: string|undefined = '';
|
||||
/// Placeholder of the Value
|
||||
@Input() placeholder: string = '';
|
||||
@Input() placeholder: string|undefined = '';
|
||||
/// The element has an error
|
||||
@Input() hasError: boolean = false;
|
||||
/// event when change the value of the password
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { AsyncActionState, AsyncActionStatusComponent } from './async-action-status/async-status-component';
|
||||
import { BurgerPropertyComponent } from './burger-property/burger-property';
|
||||
import { CheckboxComponent } from './checkbox/checkbox';
|
||||
import { EntryNumberComponent } from './entry-number/entry-number';
|
||||
import { EntryValidatorComponent } from './entry-validator/entry-validator';
|
||||
import { EntryComponent } from './entry/entry';
|
||||
import { ErrorMessageStateComponent } from './error-message-state/error-message-state';
|
||||
@ -13,4 +14,4 @@ import { SpinerComponent } from './spiner/spiner';
|
||||
import { TopMenuComponent } from './top-menu/top-menu';
|
||||
import { UploadFileComponent } from './upload-file/upload-file';
|
||||
|
||||
export { BurgerPropertyComponent, CheckboxComponent, RenderFormComponent, RenderSettingsComponent, ErrorMessageStateComponent, AsyncActionState, AsyncActionStatusComponent, EntryValidatorComponent, PopInComponent, TopMenuComponent, UploadFileComponent, ErrorComponent, SpinerComponent, PasswordEntryComponent, EntryComponent };
|
||||
export { BurgerPropertyComponent, EntryNumberComponent, CheckboxComponent, RenderFormComponent, RenderSettingsComponent, ErrorMessageStateComponent, AsyncActionState, AsyncActionStatusComponent, EntryValidatorComponent, PopInComponent, TopMenuComponent, UploadFileComponent, ErrorComponent, SpinerComponent, PasswordEntryComponent, EntryComponent };
|
||||
|
@ -1,7 +1,7 @@
|
||||
<div class="top">
|
||||
<input
|
||||
[type]="passwordVisibility?'text':'password'"
|
||||
[placeholder]="placeholder"
|
||||
[placeholder]="placeholder===undefined?'':placeholder"
|
||||
required=""
|
||||
[style.border]="hasError? '2px dashed red' : ''"
|
||||
[value]="value"
|
||||
|
@ -1,23 +1,42 @@
|
||||
<table width="100%">
|
||||
<tr *ngFor="let elem of values">
|
||||
<td width="15%" *ngIf="elem.type !== 'LINE'"
|
||||
[style.color]="elem.require && elem.value.length === 0 && elem.newValue === undefined ? 'red' : ''"
|
||||
><b>{{elem.title}}</b></td>
|
||||
<td width="85%" *ngIf="elem.type !== 'LINE'">
|
||||
<td width="15%" *ngIf="elem.type === 'STRING' || elem.type === 'PASSWORD' || elem.type === 'NUMBER'"
|
||||
[style.color]="getStyleRequireError(elem)"
|
||||
[style.font-weight]="elem.require === true ? 'bold' : ''"
|
||||
>{{elem.title}}</td>
|
||||
<td width="15%" *ngIf="elem.type === 'BOOLEAN'"
|
||||
[style.color]="getStyleRequireError(elem)"
|
||||
[style.font-weight]="elem.require === true ? 'bold' : ''"
|
||||
>{{elem.title}}</td>
|
||||
<td width="15%" *ngIf="elem.type === 'VALUE'"><b>{{elem.title}}</b></td>
|
||||
|
||||
<td width="85%" *ngIf="elem.type === 'VALUE'">{{elem.value}}</td>
|
||||
<td width="85%" *ngIf="elem.type === 'STRING'">
|
||||
<app-entry
|
||||
*ngIf="elem.type === 'STRING'"
|
||||
[value]="elem.value"
|
||||
[placeholder]="elem.placeholder"
|
||||
[hasError]="elem.state !== undefined"
|
||||
[hasError]="checkHasError(elem)"
|
||||
(changeValue)="checkParameter($event, elem)"></app-entry>
|
||||
<app-password-entry
|
||||
*ngIf="elem.type === 'PASSWORD'"
|
||||
<app-error-message-state [value]="elem.state"></app-error-message-state>
|
||||
</td>
|
||||
<td width="85%" *ngIf="elem.type === 'NUMBER'">
|
||||
<app-entry-number
|
||||
[value]="elem.value"
|
||||
[placeholder]="elem.placeholder"
|
||||
[hasError]="elem.state !== true"
|
||||
[hasError]="checkHasError(elem)"
|
||||
(changeValue)="checkParameter($event, elem)"></app-entry-number>
|
||||
<app-error-message-state [value]="elem.state"></app-error-message-state>
|
||||
</td>
|
||||
<td width="85%" *ngIf="elem.type === 'PASSWORD'">
|
||||
<app-password-entry
|
||||
[value]="elem.value"
|
||||
[placeholder]="elem.placeholder"
|
||||
[hasError]="checkHasError(elem)"
|
||||
(changeValue)="checkParameter($event, elem)"></app-password-entry>
|
||||
<app-error-message-state [value]="elem.state"></app-error-message-state>
|
||||
</td>
|
||||
<td width="85%" *ngIf="elem.type === 'BOOLEAN'">
|
||||
<app-checkbox
|
||||
*ngIf="elem.type === 'BOOLEAN'"
|
||||
[value]="elem.value"
|
||||
(changeValue)="checkParameter($event, elem)"></app-checkbox>
|
||||
<app-error-message-state [value]="elem.state"></app-error-message-state>
|
||||
|
@ -7,20 +7,21 @@ import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { isBoolean, isInArray, isNullOrUndefined, isNumber, isObject, isOptionalOf, isString, isUndefined } from 'common/utils';
|
||||
|
||||
export type ReturnFunction = (a: boolean|string) => void;
|
||||
|
||||
export type CheckerParameterType = string | number | boolean | undefined;
|
||||
// if string ==> the error, if undefined, it is OK
|
||||
export type CheckerParameter = (value: string) => string | undefined;
|
||||
|
||||
export type CheckerParameter = (value: CheckerParameterType) => string | undefined;
|
||||
|
||||
|
||||
export enum SettingType {
|
||||
VALUE = 'VALUE',
|
||||
LINE = 'LINE',
|
||||
BOOLEAN = 'BOOLEAN',
|
||||
NUMBER = 'NUMBER',
|
||||
STRING = 'STRING',
|
||||
PASSWORD = 'PASSWORD',
|
||||
}
|
||||
export function isSettingType(data: any): data is SettingType {
|
||||
return isInArray(data, ['LINE', 'BOOLEAN', 'STRING', 'PASSWORD']);
|
||||
return isInArray(data, ['VALUE', 'LINE', 'NUMBER', 'BOOLEAN', 'STRING', 'PASSWORD']);
|
||||
}
|
||||
|
||||
export interface SettingsItem {
|
||||
@ -101,7 +102,7 @@ export class RenderSettingsComponent {
|
||||
/// event with the changed values
|
||||
@Output() deltaValues: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
createOutputValues(): any {
|
||||
createOutputValues(): object {
|
||||
let out = {};
|
||||
//console.log(" Create values ... out ... ");
|
||||
this.values.forEach( (value) => {
|
||||
@ -129,16 +130,50 @@ export class RenderSettingsComponent {
|
||||
|
||||
checkMissing(): boolean | undefined {
|
||||
let error = 0;
|
||||
this.values.forEach( (value) => {
|
||||
if (value.require === true && value.value === "" && isUndefined(value.newValue) ) {
|
||||
error++;
|
||||
this.values.forEach( (elem) => {
|
||||
if (isNumber(elem.newValue)) {
|
||||
if ((isUndefined(elem.newValue) && elem.value === undefined) || elem.newValue === undefined) {
|
||||
error++;
|
||||
}
|
||||
} else {
|
||||
if ((isUndefined(elem.newValue) && elem.value === "") || elem.newValue === "") {
|
||||
error++;
|
||||
}
|
||||
}
|
||||
});
|
||||
return error !== 0;
|
||||
}
|
||||
|
||||
getStyleRequireError(elem): string {
|
||||
if (elem.require !== true) {
|
||||
return "";
|
||||
}
|
||||
if (isNumber(elem.newValue)) {
|
||||
//console.log(`>>>>>>>>>>>>>>>>>>>>>>>>>>>>><Is a number : ${elem.newValue} ${elem.value}`)
|
||||
if ((isUndefined(elem.newValue) && elem.value === undefined) || elem.newValue === undefined) {
|
||||
return "red";
|
||||
}
|
||||
} else {
|
||||
if ((isUndefined(elem.newValue) && elem.value === "") || elem.newValue === "") {
|
||||
return "red";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
checkParameter(newValue: string, item: SettingsItem): void {
|
||||
if (!isNullOrUndefined(item.checker)) {
|
||||
checkHasError(item: SettingsItem) {
|
||||
if (!isUndefined(item.state)) {
|
||||
return true;
|
||||
}
|
||||
if (item.require === true && item.value === "" && isUndefined(item.newValue)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
checkParameter(newValue: string | number | boolean | undefined, item: SettingsItem): void {
|
||||
if (isNullOrUndefined(newValue) || newValue === "") {
|
||||
item.state = undefined
|
||||
} else if (!isNullOrUndefined(item.checker)) {
|
||||
item.state = item.checker(newValue);
|
||||
}
|
||||
if (item.value === newValue) {
|
||||
|
Loading…
Reference in New Issue
Block a user