Adding angular code

This commit is contained in:
Martin Stockhammer 2020-11-02 14:24:30 +01:00
parent ee7d339b45
commit 108b60a4df
43 changed files with 2267 additions and 1739 deletions

View File

@ -689,6 +689,7 @@
<exclude>src/main/archiva-web/src/polyfills.ts</exclude> <exclude>src/main/archiva-web/src/polyfills.ts</exclude>
<exclude>src/main/archiva-web/e2e/protractor.conf.js</exclude> <exclude>src/main/archiva-web/e2e/protractor.conf.js</exclude>
<exclude>src/main/archiva-web/e2e/tsconfig.json</exclude> <exclude>src/main/archiva-web/e2e/tsconfig.json</exclude>
<exclude>src/main/archiva-web/src/assets/i18n/*.json</exclude>
</excludes> </excludes>
</configuration> </configuration>
</plugin> </plugin>
@ -735,7 +736,7 @@
<webApp> <webApp>
<contextPath>/archiva</contextPath> <contextPath>/archiva</contextPath>
</webApp> </webApp>
<jettyXml>${basedir}/src/test/jetty-env.xml</jettyXml> <jettyXml>${basedir}/src/test/resources/jetty-env.xml</jettyXml>
<systemProperties> <systemProperties>
<systemProperty> <systemProperty>
<name>plexus.home</name> <name>plexus.home</name>
@ -787,7 +788,7 @@
</systemProperty> </systemProperty>
<systemProperty> <systemProperty>
<name>log4j.configurationFile</name> <name>log4j.configurationFile</name>
<value>${basedir}/src/test/log4j2-test.xml</value> <value>${basedir}/src/test/resources/log4j2-test.xml</value>
</systemProperty> </systemProperty>
<systemProperty> <systemProperty>
<name>AsyncLoggerConfig.WaitStrategy</name> <name>AsyncLoggerConfig.WaitStrategy</name>
@ -801,8 +802,12 @@
<name>openjpa.Log</name> <name>openjpa.Log</name>
<value>${openjpa.Log}</value> <value>${openjpa.Log}</value>
</systemProperty> </systemProperty>
<systemProperty>
<name>redback.admin.creation.file</name>
<value>${basedir}/src/test/resources/auto-admin-creation.properties</value>
</systemProperty>
</systemProperties> </systemProperties>
<useTestScope>false</useTestScope> <useTestScope>true</useTestScope>
</configuration> </configuration>
<dependencies> <dependencies>
<dependency> <dependency>

View File

@ -2,26 +2,36 @@
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.0.1. This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.0.1.
## Development server ## Usage instructions
### Development server
Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding ### Code scaffolding
Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
## Build ### Build
Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build. Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `--prod` flag for a production build.
## Running unit tests ### Running unit tests
Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests ### Running end-to-end tests
Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
## Further help ### Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).
## Information about used components
### I18n-Support
We are using the ngx-translate package for i18n, and not the builtin localization of angular 9.+ . Because, the builtin module
does not allow runtime translations by keys. All keys must exist during compile phase.

View File

@ -13,10 +13,14 @@
"root": "", "root": "",
"sourceRoot": "src", "sourceRoot": "src",
"prefix": "app", "prefix": "app",
"i18n": {
"sourceLocale": "en-US"
},
"architect": { "architect": {
"build": { "build": {
"builder": "@angular-devkit/build-angular:browser", "builder": "@angular-devkit/build-angular:browser",
"options": { "options": {
"localize": false,
"outputPath": "dist/archiva-web", "outputPath": "dist/archiva-web",
"index": "src/index.html", "index": "src/index.html",
"main": "src/main.ts", "main": "src/main.ts",
@ -79,12 +83,6 @@
} }
} }
}, },
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "archiva-web:build"
}
},
"test": { "test": {
"builder": "@angular-devkit/build-angular:karma", "builder": "@angular-devkit/build-angular:karma",
"options": { "options": {

View File

@ -1,3 +1,21 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// @ts-check // @ts-check
// Protractor configuration file, see link for more information // Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts // https://github.com/angular/protractor/blob/master/lib/config.ts

View File

@ -1,6 +1,6 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */ /* To learn more about this file see: https://angular.io/config/tsconfig. */
{ {
"extends": "../tsconfig.base.json", "extends": "../tsconfig.json",
"compilerOptions": { "compilerOptions": {
"outDir": "../out-tsc/e2e", "outDir": "../out-tsc/e2e",
"module": "commonjs", "module": "commonjs",

View File

@ -1,3 +1,21 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
// Karma configuration file, see link for more information // Karma configuration file, see link for more information
// https://karma-runner.github.io/1.0/config/configuration-file.html // https://karma-runner.github.io/1.0/config/configuration-file.html

View File

@ -11,27 +11,30 @@
}, },
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "~10.0.2", "@angular/animations": "~10.2.0",
"@angular/common": "~10.0.2", "@angular/common": "~10.2.0",
"@angular/compiler": "~10.0.2", "@angular/compiler": "~10.2.0",
"@angular/core": "~10.0.2", "@angular/core": "~10.2.0",
"@angular/forms": "~10.0.2", "@angular/forms": "~10.2.0",
"@angular/localize": "^10.0.2", "@angular/platform-browser": "~10.2.0",
"@angular/platform-browser": "~10.0.2", "@angular/platform-browser-dynamic": "~10.2.0",
"@angular/platform-browser-dynamic": "~10.0.2", "@angular/router": "~10.2.0",
"@angular/router": "~10.0.2",
"@fortawesome/fontawesome-free": "^5.13.1", "@fortawesome/fontawesome-free": "^5.13.1",
"@fortawesome/fontawesome-svg-core": "^1.2.29", "@fortawesome/fontawesome-svg-core": "^1.2.29",
"@ngx-translate/core": "^13.0.0",
"@ngx-translate/http-loader": "^6.0.0",
"bootstrap": "^4.5.0", "bootstrap": "^4.5.0",
"flag-icon-css": "^3.5.0",
"jquery": "^3.5.1", "jquery": "^3.5.1",
"rxjs": "~6.5.5", "rxjs": "~6.6.3",
"service": "^0.1.4",
"tslib": "^2.0.0", "tslib": "^2.0.0",
"zone.js": "~0.10.3" "zone.js": "~0.10.3"
}, },
"devDependencies": { "devDependencies": {
"@angular-devkit/build-angular": "~0.1000.1", "@angular-devkit/build-angular": "~0.1002.0",
"@angular/cli": "~10.0.1", "@angular/cli": "~10.2.0",
"@angular/compiler-cli": "~10.0.2", "@angular/compiler-cli": "~10.2.0",
"@types/node": "^12.11.1", "@types/node": "^12.11.1",
"@types/jasmine": "~3.5.0", "@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3", "@types/jasminewd2": "~2.0.3",

View File

@ -22,8 +22,8 @@ import { Routes, RouterModule } from '@angular/router';
import { AboutComponent } from './modules/general/about/about.component'; import { AboutComponent } from './modules/general/about/about.component';
import { ContactComponent } from './modules/general/contact/contact.component'; import { ContactComponent } from './modules/general/contact/contact.component';
import { HomeComponent } from './modules/general/home/home.component'; import { HomeComponent } from './modules/general/home/home.component';
import { LoginComponent } from './modules/general/login/login.component';
import { NotFoundComponent } from './modules/general/not-found/not-found.component'; import { NotFoundComponent } from './modules/general/not-found/not-found.component';
import { LoginComponent } from "./modules/general/login/login.component";
const routes: Routes = [ const routes: Routes = [
{ path: '', component: HomeComponent, }, { path: '', component: HomeComponent, },

View File

@ -29,28 +29,35 @@
<div class="collapse navbar-collapse" id="navbarsDefault"> <div class="collapse navbar-collapse" id="navbarsDefault">
<ul class="navbar-nav ml-auto"> <ul class="navbar-nav ml-auto">
<li class="nav-item active"> <li class="nav-item active">
<a i18n="navbar|" class="nav-link" routerLink="/"> <a class="nav-link" routerLink="/">
<i class="fas fa-home mr-1"></i>Home <i class="fas fa-home mr-1"></i>{{ 'menu.home' |translate }}
</a> </a>
</li> </li>
<li class="nav-item active"> <li class="nav-item active">
<a i18n="navbar|" class="nav-link" routerLink="/about"> <a class="nav-link" routerLink="/login" data-toggle="modal" data-target="#loginModal">
<i class="far fa-question-circle mr-1"></i>About <i class="fas fa-user mr-1"></i>{{'menu.login' | translate}}
</a>
</li>
<li class="nav-item active dropdown">
<a class="nav-link dropdown-toggle" id="dropdown09" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><span class="flag-icon {{langIcon()}}"></span></a>
<div class="dropdown-menu" aria-labelledby="dropdown09">
<a class="dropdown-item" href="#en" (click)="switchLang('en')"><span class="flag-icon flag-icon-gb"> </span> English</a>
<a class="dropdown-item" href="#de" (click)="switchLang('de')"><span class="flag-icon flag-icon-de"> </span> German</a>
</div>
</li>
<li class="nav-item active">
<a class="nav-link" routerLink="/about">
<i class="far fa-question-circle mr-1"></i>{{'menu.about' | translate}}
</a> </a>
</li> </li>
<li class="nav-item active"> <li class="nav-item active">
<a i18n="navbar|" class="nav-link" routerLink="/contact"> <a class="nav-link" routerLink="/contact">
<i class="fas fa-envelope mr-1"></i>Contact <i class="fas fa-envelope mr-1"></i>{{ 'menu.contact' | translate }}
</a>
</li>
<li class="nav-item active">
<a i18n="navbar|" class="nav-link" routerLink="/login">
<i class="fas fa-user mr-1"></i>Login
</a> </a>
</li> </li>
<li class="nav-item active"> <li class="nav-item active">
<a class="nav-link" href="https://github.com/apache/archiva"> <a class="nav-link" href="https://github.com/apache/archiva">
<i class="fab fa-github mr-1"></i>Github <i class="fab fa-github mr-1"></i>
</a> </a>
</li> </li>
</ul> </ul>

View File

@ -17,6 +17,7 @@
* under the License. * under the License.
*/ */
import { Component } from '@angular/core'; import { Component } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
@ -26,4 +27,27 @@ import { Component } from '@angular/core';
export class AppComponent { export class AppComponent {
title = 'archiva-web'; title = 'archiva-web';
version = 'Angular version 10.0.2'; version = 'Angular version 10.0.2';
constructor(
public translate: TranslateService
) {
translate.addLangs(['en', 'de']);
translate.setDefaultLang('en');
translate.use('en');
}
switchLang(lang: string) {
this.translate.use(lang);
}
langIcon() : string {
switch (this.translate.currentLang) {
case "de":
return "flag-icon-de";
case "en":
return "flag-icon-gb";
default:
return "flag-icon-" + this.translate.currentLang;
}
}
} }

View File

@ -18,17 +18,19 @@
*/ */
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http'; import { HttpClient, HttpClientModule } from '@angular/common/http';
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { HomeComponent } from './modules/general/home/home.component'; import { HomeComponent } from './modules/general/home/home.component';
import { ContactComponent } from './modules/general/contact/contact.component'; import { ContactComponent } from './modules/general/contact/contact.component';
import { AboutComponent } from './modules/general/about/about.component'; import { AboutComponent } from './modules/general/about/about.component';
import { LoginComponent } from './modules/general/login/login.component';
import { NotFoundComponent } from './modules/general/not-found/not-found.component'; import { NotFoundComponent } from './modules/general/not-found/not-found.component';
import { SidemenuComponent } from './modules/general/sidemenu/sidemenu.component'; import { SidemenuComponent } from './modules/general/sidemenu/sidemenu.component';
import {FormsModule} from "@angular/forms"; import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import { LoginComponent } from './modules/general/login/login.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -36,17 +38,29 @@ import {FormsModule} from "@angular/forms";
HomeComponent, HomeComponent,
ContactComponent, ContactComponent,
AboutComponent, AboutComponent,
LoginComponent,
NotFoundComponent, NotFoundComponent,
SidemenuComponent, SidemenuComponent,
LoginComponent,
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
AppRoutingModule, AppRoutingModule,
FormsModule, FormsModule,
ReactiveFormsModule,
HttpClientModule, HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: httpTranslateLoader,
deps: [HttpClient]
}
})
], ],
providers: [], providers: [],
bootstrap: [AppComponent] bootstrap: [AppComponent]
}) })
export class AppModule { } export class AppModule { }
export function httpTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http);
}

View File

@ -16,19 +16,11 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { TestBed } from '@angular/core/testing';
import { LoginService } from './login.service'; import { AccessToken } from './access-token';
describe('LoginService', () => { describe('AccessToken', () => {
let service: LoginService; it('should create an instance', () => {
expect(new AccessToken()).toBeTruthy();
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(LoginService);
});
it('should be created', () => {
expect(service).toBeTruthy();
}); });
}); });

View File

@ -16,19 +16,11 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { Injectable } from '@angular/core'; export class AccessToken {
import { ArchivaRequestService } from "./archiva-request.service"; access_token: string;
refresh_token: string;
expires_in: number;
@Injectable({ token_type: string;
providedIn: 'root' scope: string;
}) state: string;
export class LoginService {
login(username: string, password: string) {
throw new Error("Method not implemented.");
}
constructor(private archiva : ArchivaRequestService) { }
} }

View File

@ -0,0 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ErrorMessage } from './error-message';
describe('ErrorMessage', () => {
it('should create an instance', () => {
expect(new ErrorMessage()).toBeTruthy();
});
});

View File

@ -16,11 +16,8 @@
* under the License. * under the License.
*/ */
export class Logindata { export class ErrorMessage {
errorKey: string;
constructor( args: string[];
public username: string, message: string;
public password: string
) { }
} }

View File

@ -0,0 +1,27 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { ErrorResult } from './error-result';
import { ErrorMessage } from './error-message';
describe('ErrorResult', () => {
it('should create an instance', () => {
const resultArray = new ErrorMessage[0]();
expect(resultArray).toBeTruthy();
});
});

View File

@ -0,0 +1,27 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import {ErrorMessage} from "./error-message";
export class ErrorResult {
errorMessages: Array<ErrorMessage>
constructor(errorMessages: Array<ErrorMessage>) {
this.errorMessages = errorMessages;
}
}

View File

@ -16,36 +16,38 @@
~ specific language governing permissions and limitations ~ specific language governing permissions and limitations
~ under the License. ~ under the License.
--> -->
<div class="container-md" >
<div class="row">
<div class="col-6">
<form (ngSubmit)="onSubmit()" #loginForm="ngForm">
<div class="form-group">
<label for="username" i18n="loginform|">Username</label>
<input type="text" class="form-control" id="username" aria-describedby="usernameHelp"
required name="username"
[(ngModel)]="model.username" #username="ngModel"
>
<small id="usernameHelp" class="form-text text-muted" i18n="inputhelp|">Enter your username.</small>
<div [hidden]="username.valid || username.pristine" <!-- Modal -->
class="alert alert-danger" i18n> <div class="modal fade" id="loginModal" tabindex="-1" role="dialog" aria-labelledby="loginModal" aria-hidden="true">
Username is required <div class="modal-dialog" role="document">
<form [formGroup]="loginForm" (ngSubmit)="login(loginForm.value)" >
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="loginModalLabel">{{'login.title'|translate}}</h5>
<button type="button" #closebutton class="close" data-dismiss="modal" aria-label="Close" >
<span aria-hidden="true">&times;</span>
</button>
</div> </div>
<div class="modal-body">
<div class="form-group">
<label for="userid" id="userid-label" >{{'login.userid' | translate}}</label>
<input id="userid" aria-labelledby="userid-label" class="form-control" placeholder="userid" formControlName="userid" />
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="password" i18n="loginform|">Password</label> <label for="password" id="password-label" >{{'login.password' | translate}}</label>
<input type="password" class="form-control" id="password" name="password" <input id="password" aria-labelledby="password-label" class="form-control" type="password" formControlName="password" />
required="required" [(ngModel)]="model.password" #password="ngModel" </div>
> </div>
<small id="passwordHelp" class="form-text text-muted" i18n="inputhelp|">Enter your password.</small> <div class="modal-footer">
<div [hidden]="password.valid || password.pristine" <button type="button" class="btn btn-secondary" data-dismiss="modal" >{{'modal.close'|translate}}</button>
class="alert alert-danger" i18n> <button type="button" class="btn btn-primary" type="submit" >{{'login.submit'|translate}}</button>
Password is required
</div> </div>
</div> </div>
<button type="submit" class="btn btn-primary">Submit</button>
</form> </form>
<div *ngFor="let msg of errorMessages" class="alert alert-danger" >
{{msg}}
</div>
</div> </div>
</div> </div>
</div>

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { LoginComponent } from './login.component'; import { LoginComponent } from './login.component';
@ -24,12 +24,12 @@ describe('LoginComponent', () => {
let component: LoginComponent; let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>; let fixture: ComponentFixture<LoginComponent>;
beforeEach(async(() => { beforeEach(async () => {
TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ LoginComponent ] declarations: [ LoginComponent ]
}) })
.compileComponents(); .compileComponents();
})); });
beforeEach(() => { beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent); fixture = TestBed.createComponent(LoginComponent);

View File

@ -16,11 +16,13 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
import { Component, OnInit } from '@angular/core'; import {Component, OnInit, ViewChild} from '@angular/core';
// noinspection ES6UnusedImports import { FormBuilder } from '@angular/forms';
import { FormsModule } from "@angular/forms"; import { AuthenticationService } from "../../../services/authentication.service";
import { Logindata } from "../../../logindata"; import {AccessToken} from "../../../model/access-token";
import { LoginService } from "../../../services/login.service"; import {ErrorMessage} from "../../../model/error-message";
import {Router} from "@angular/router";
import {ArchivaRequestService} from "../../../services/archiva-request.service";
@Component({ @Component({
selector: 'app-login', selector: 'app-login',
@ -29,21 +31,47 @@ import { LoginService } from "../../../services/login.service";
}) })
export class LoginComponent implements OnInit { export class LoginComponent implements OnInit {
model = new Logindata('', ''); @ViewChild("closebutton") closebutton;
submitted = false; loginForm;
userid;
password;
errorMessages : string[];
onSubmit() { this.submitted = true; } constructor( private authenticationService: AuthenticationService,
private formBuilder: FormBuilder,
private router: Router,
private archivaRequest : ArchivaRequestService ) {
this.loginForm = this.formBuilder.group({
userid: '',
password: '',
});
this.errorMessages = [];
get diagnostic() { return JSON.stringify(this.submitted); }
login(): void {
this.loginService.login(username, password);
} }
constructor(private loginService: LoginService) { }
ngOnInit(): void { ngOnInit(): void {
} }
login(customerData) {
this.errorMessages = [];
let resultHandler = (result: string, err?: ErrorMessage[] ) => {
if (result=="OK") {
this.closebutton.nativeElement.click();
this.router.navigate(["/"]);
} else if (result=="ERROR") {
if (err != null) {
this.errorMessages = [];
for (let msg of err) {
console.log("Error "+msg.errorKey);
this.errorMessages.push(this.archivaRequest.translateError(msg));
}
}
}
}
// Process checkout data here
this.loginForm.reset();
this.authenticationService.login(customerData.userid, customerData.password, resultHandler);
}
} }

View File

@ -18,51 +18,51 @@
--> -->
<nav class="nav flex-column nav-pills " role="tablist" aria-orientation="vertical"> <nav class="nav flex-column nav-pills " role="tablist" aria-orientation="vertical">
<a i18n="sidemenu|" class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Artifacts</a> <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Artifacts</a>
<a i18n="sidemenu|" class="nav-link active my-0 py-0" href="#" data-toggle="pill" <a class="nav-link active my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-search" aria-selected="true">Search</a> role="tab" aria-controls="v-pills-search" aria-selected="true">Search</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Browse</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Browse</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Upload Artifact</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Upload Artifact</a>
<a i18n="sidemenu|" class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true" data-toggle="pill" <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true" data-toggle="pill"
role="tab" aria-controls="v-pills-home" aria-selected="false">Administration</a> role="tab" aria-controls="v-pills-home" aria-selected="false">Administration</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Repository Groups</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Repository Groups</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Repositories</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Repositories</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Proxy Connectors</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Proxy Connectors</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">ProxyConnector Rules</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">ProxyConnector Rules</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Network Proxies</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Network Proxies</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Repository Scanning</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Repository Scanning</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Runtime Configuration</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Runtime Configuration</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">System Status</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">System Status</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">UI Configuration</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">UI Configuration</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Reports</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Reports</a>
<a i18n="sidemenu|" class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true" data-toggle="pill" <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true" data-toggle="pill"
role="tab" aria-controls="v-pills-home" aria-selected="false">Users</a> role="tab" aria-controls="v-pills-home" aria-selected="false">Users</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Manage</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Manage</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Roles</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Roles</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">Users Runtime Configuration</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">Users Runtime Configuration</a>
<a i18n="sidemenu|" class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true" data-toggle="pill" <a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true" data-toggle="pill"
role="tab" aria-controls="v-pills-home" aria-selected="false">Documentation</a> role="tab" aria-controls="v-pills-home" aria-selected="false">Documentation</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">REST Api</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">REST Api</a>
<a i18n="sidemenu|" class="nav-link my-0 py-0" href="#" data-toggle="pill" <a class="nav-link my-0 py-0" href="#" data-toggle="pill"
role="tab" aria-controls="v-pills-browse" aria-selected="false">User Documentation</a> role="tab" aria-controls="v-pills-browse" aria-selected="false">User Documentation</a>
</nav> </nav>

View File

@ -17,24 +17,48 @@
* under the License. * under the License.
*/ */
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient } from "@angular/common/http"; import {HttpClient, HttpEvent, HttpResponse} from "@angular/common/http";
import { environment } from "../../environments/environment"; import { environment } from "../../environments/environment";
import {Observable} from "rxjs";
import {ErrorMessage} from "../model/error-message";
import {TranslateService} from "@ngx-translate/core";
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
}) })
export class ArchivaRequestService { export class ArchivaRequestService {
constructor(private http : HttpClient, private translator : TranslateService) { }
executeRestCall(type: string, module: string, service: string, input: object, callback: (result: object) => void ) : void { executeRestCall<R>(type: string, module: string, service: string, input: object ) : Observable<R> {
let modulePath = environment.application.servicePaths[module]; let modulePath = environment.application.servicePaths[module];
let url = environment.application.baseUrl + environment.application.restPath + "/"+modulePath+"/" + service + "Service"; let url = environment.application.baseUrl + environment.application.restPath + "/" + modulePath + "/" + service;
let token = localStorage.getItem("access_token")
let headers = null;
if (token != null) {
headers = {
"Authorization": "Bearer " + localStorage.getItem("access_token")
}
} else {
headers = {};
}
if (type == "get") { if (type == "get") {
this.http.get(url,) return this.http.get<R>(url, {"headers":headers});
} else if ( type == "post") { } else if ( type == "post") {
this.http.post(url); return this.http.post<R>(url, input, {"headers":headers});
} }
} }
constructor(private http : HttpClient) { }
translateError(errorMsg : ErrorMessage) : string {
if (errorMsg.errorKey!=null && errorMsg.errorKey!='') {
let parms = {};
if (errorMsg.args!=null && errorMsg.args.length>0) {
for ( let i=0; i<errorMsg.args.length; i++) {
parms['arg' + i] = errorMsg.args[i];
}
}
return this.translator.instant('api.'+errorMsg.errorKey, parms);
}
}
} }

View File

@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { TestBed } from '@angular/core/testing';
import { AuthenticationService } from './authentication.service';
import {of, throwError} from 'rxjs';
import {ArchivaRequestService} from "./archiva-request.service";
import { ErrorMessage } from '../model/error-message';
import {HttpErrorResponse} from "@angular/common/http";
describe('AuthenticationService', () => {
let service: AuthenticationService;
let archivaRequestServiceSpy: jasmine.SpyObj<ArchivaRequestService>;
beforeEach(() => {
const spy = jasmine.createSpyObj('ArchivaRequestService', ['executeRestCall']);
TestBed.configureTestingModule( { providers: [
AuthenticationService,
{ provide: ArchivaRequestService, useValue: spy }
]});
service = TestBed.inject(AuthenticationService);
archivaRequestServiceSpy = TestBed.inject(ArchivaRequestService) as jasmine.SpyObj<ArchivaRequestService>;
});
it('should be created', () => {
expect(service).toBeTruthy();
});
it('#login should return success and set token', () => {
const stubValue = {'access_token':'abcdefg','refresh_token':'hijklmnop','expires_in':1000};
archivaRequestServiceSpy.executeRestCall.and.returnValue(of(stubValue));
// resultHandler: (n: string, err?: ErrorMessage[]) => void
let result:string;
let handler = (n:string, err?:ErrorMessage[]) => {
result = n;
};
service.login('admin','pass123', handler);
expect(result).toEqual("OK");
expect(archivaRequestServiceSpy.executeRestCall.calls.count()).toBe(1, 'one call');
expect(localStorage.getItem('access_token')).toEqual("abcdefg");
expect(localStorage.getItem('refresh_token')).toEqual("hijklmnop");
});
it('#login fails', () => {
const stubValue = {'access_token':'abcdefg','refresh_token':'hijklmnop','expires_in':1000};
archivaRequestServiceSpy.executeRestCall.and.returnValue(throwError(new HttpErrorResponse({'status':404, error:{'errorMessages':[
new ErrorMessage()
]}})));
// resultHandler: (n: string, err?: ErrorMessage[]) => void
let result : string;
let messages: ErrorMessage[];
let handler = (n:string, err?:ErrorMessage[]) => {
result = n;
messages = err;
};
service.login('admin', 'test', handler);
expect(result).toEqual("ERROR");
expect(messages).toBeTruthy();
expect(messages.length).toEqual(1);
});
});

View File

@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { Injectable } from '@angular/core';
import {ArchivaRequestService} from "./archiva-request.service";
import {AccessToken} from "../model/access-token";
import { environment } from "../../environments/environment";
import {ErrorMessage} from "../model/error-message";
import {ErrorResult} from "../model/error-result";
import {HttpErrorResponse} from "@angular/common/http";
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
constructor(private rest: ArchivaRequestService) { }
login(userid:string, password:string, resultHandler: (n: string, err?: ErrorMessage[]) => void) {
const data = { 'grant_type':'authorization_code',
'client_id':environment.application.client_id,
'user_id':userid, 'password':password
};
let authObserver = this.rest.executeRestCall<AccessToken>('post','redback', 'auth/authenticate', data );
let tokenObserver = {
next: (x: AccessToken) => {
localStorage.setItem("access_token", x.access_token);
localStorage.setItem("refresh_token", x.refresh_token);
if (x.expires_in!=null) {
let dt = new Date();
dt.setSeconds(dt.getSeconds() + x.expires_in);
localStorage.setItem("token_expire", dt.toISOString());
}
resultHandler("OK");
},
error: ( err: HttpErrorResponse) => {
console.log("Error " + (JSON.stringify(err)));
let result = err.error as ErrorResult
if (result.errorMessages!=null) {
for (let msg of result.errorMessages) {
console.error('Observer got an error: ' + msg.errorKey)
}
resultHandler("ERROR", result.errorMessages);
} else {
resultHandler("ERROR", null);
}
},
// complete: () => console.log('Observer got a complete notification'),
};
authObserver.subscribe(tokenObserver)
}
logout() {
localStorage.removeItem("access_token");
localStorage.removeItem("refresh_token");
localStorage.removeItem("token_expire");
}
}

View File

@ -0,0 +1,20 @@
{
"login": {
"title": "Anmelden bei Archiva",
"password": "Passwort",
"userid": "User Id",
"submit": "Anmelden"
},
"modal" : {
"close":"Schließen"
},
"menu": {
"home": "Home",
"login": "Anmelden",
"about": "Über",
"contact": "Kontakt"
},
"api" : {
"rb.auth.invalid_credentials": "Anmeldedaten ungültig"
}
}

View File

@ -0,0 +1,20 @@
{
"login": {
"title": "Login to Archiva",
"password": "Password",
"userid": "User Id",
"submit": "Login"
},
"modal" : {
"close": "Close"
},
"menu": {
"home": "Home",
"login": "Login",
"about": "About",
"contact": "Contact"
},
"api" : {
"rb.auth.invalid_credentials": "Invalid credentials given"
}
}

View File

@ -25,15 +25,16 @@ export const environment = {
production: false, production: false,
application: application:
{ {
client_id:'archiva_web_client',
baseUrl: 'http://localhost:8080', baseUrl: 'http://localhost:8080',
restPath: '/restServices', restPath: '/archiva/api/v2',
servicePaths: { servicePaths: {
archiva:"archivaServices", archiva:"archiva",
redback:"redbackServices", redback:"redback",
ui:"archivaUiServices" ui:"archivaUi"
}, },
name: 'archiva-starter', name: 'archiva-starter',
angular: 'Angular 10.0.2', angular: 'Angular 10.2.0',
bootstrap: 'Bootstrap 4.5.0', bootstrap: 'Bootstrap 4.5.0',
fontawesome: 'Font Awesome 5.13.1' fontawesome: 'Font Awesome 5.13.1'
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 948 B

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -1,3 +1,21 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
-->
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<!-- <!--

View File

@ -1,102 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!--
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
-->
<xliff version="2.0" xmlns="urn:oasis:names:tc:xliff:document:2.0" srcLang="en-US">
<file original="ng.template" id="ngi18n">
<unit id="3533320232395919182">
<notes>
<note category="meaning">sidenav</note>
<note category="location">src/app/app.component.html:33,35</note>
</notes>
<segment>
<source>
<pc id="0" equivStart="START_ITALIC_TEXT" equivEnd="CLOSE_ITALIC_TEXT" type="fmt" dispStart="&lt;i&gt;" dispEnd="&lt;/i&gt;"></pc>Home
</source>
</segment>
</unit>
<unit id="1283530642863181542">
<notes>
<note category="meaning">sidenav</note>
<note category="location">src/app/app.component.html:38,40</note>
</notes>
<segment>
<source>
<pc id="0" equivStart="START_ITALIC_TEXT" equivEnd="CLOSE_ITALIC_TEXT" type="fmt" dispStart="&lt;i&gt;" dispEnd="&lt;/i&gt;"></pc>About
</source>
</segment>
</unit>
<unit id="4789449765292606242">
<notes>
<note category="meaning">sidenav</note>
<note category="location">src/app/app.component.html:43,45</note>
</notes>
<segment>
<source>
<pc id="0" equivStart="START_ITALIC_TEXT" equivEnd="CLOSE_ITALIC_TEXT" type="fmt" dispStart="&lt;i&gt;" dispEnd="&lt;/i&gt;"></pc>Contact
</source>
</segment>
</unit>
<unit id="1912174959280479645">
<notes>
<note category="meaning">sidenav</note>
<note category="location">src/app/app.component.html:48,50</note>
</notes>
<segment>
<source>
<pc id="0" equivStart="START_ITALIC_TEXT" equivEnd="CLOSE_ITALIC_TEXT" type="fmt" dispStart="&lt;i&gt;" dispEnd="&lt;/i&gt;"></pc>Login
</source>
</segment>
</unit>
<unit id="6511475824238507681">
<notes>
<note category="location">src/app/modules/general/home/home.component.html:22</note>
</notes>
<segment>
<source>Artifacts</source>
</segment>
</unit>
<unit id="4580988005648117665">
<notes>
<note category="location">src/app/modules/general/home/home.component.html:24</note>
</notes>
<segment>
<source>Search</source>
</segment>
</unit>
<unit id="787163983066183218">
<notes>
<note category="location">src/app/modules/general/home/home.component.html:26</note>
</notes>
<segment>
<source>Browse</source>
</segment>
</unit>
<unit id="7844706011418789951">
<notes>
<note category="location">src/app/modules/general/home/home.component.html:28</note>
</notes>
<segment>
<source>Administration</source>
</segment>
</unit>
</file>
</xliff>

View File

@ -1,7 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/*************************************************************************************************** /***************************************************************************************************
* Load `$localize` onto the global scope - used if i18n tags appear in Angular templates. * Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
*/ */
import '@angular/localize/init'; // import '@angular/localize/init';
/** /**
* This file includes polyfills needed by Angular and is loaded before the app. * This file includes polyfills needed by Angular and is loaded before the app.
* You can add your own extra polyfills to this file. * You can add your own extra polyfills to this file.

View File

@ -43,6 +43,7 @@ body {
} }
@import "~bootstrap/scss/bootstrap"; @import "~bootstrap/scss/bootstrap";
@import "~flag-icon-css/css/flag-icon.min.css";

View File

@ -1,6 +1,6 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */ /* To learn more about this file see: https://angular.io/config/tsconfig. */
{ {
"extends": "./tsconfig.base.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"outDir": "./out-tsc/app", "outDir": "./out-tsc/app",
"types": [] "types": []

View File

@ -1,20 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"downlevelIteration": true,
"experimentalDecorators": true,
"moduleResolution": "node",
"importHelpers": true,
"target": "es2015",
"module": "es2020",
"lib": [
"es2018",
"dom"
]
}
}

View File

@ -1,20 +1,20 @@
/* /* To learn more about this file see: https://angular.io/config/tsconfig. */
This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScripts language server to improve development experience.
It is not intended to be used to perform a compilation.
To learn more about this file see: https://angular.io/config/solution-tsconfig.
*/
{ {
"files": [], "compileOnSave": false,
"references": [ "compilerOptions": {
{ "baseUrl": "./",
"path": "./tsconfig.app.json" "outDir": "./dist/out-tsc",
}, "sourceMap": true,
{ "declaration": false,
"path": "./tsconfig.spec.json" "downlevelIteration": true,
}, "experimentalDecorators": true,
{ "moduleResolution": "node",
"path": "./e2e/tsconfig.json" "importHelpers": true,
"target": "es2015",
"module": "es2020",
"lib": [
"es2018",
"dom"
]
} }
]
} }

View File

@ -1,6 +1,6 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */ /* To learn more about this file see: https://angular.io/config/tsconfig. */
{ {
"extends": "./tsconfig.base.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"outDir": "./out-tsc/spec", "outDir": "./out-tsc/spec",
"types": [ "types": [

View File

@ -91,12 +91,6 @@
<logger name="net.sf.ehcache" level="warn"/> <logger name="net.sf.ehcache" level="warn"/>
<!-- retained for Redback --> <!-- retained for Redback -->
<logger name="JPOX" level="warn"/>
<logger name="JPOX.MetaData" level="error"/>
<logger name="JPOX.RDBMS.SQL" level="error"/>
<logger name="SQL" level="error"/> <logger name="SQL" level="error"/>
<logger name="org.apache.commons.configuration.DefaultConfigurationBuilder" level="error"/> <logger name="org.apache.commons.configuration.DefaultConfigurationBuilder" level="error"/>
@ -117,7 +111,9 @@
--> -->
<root level="info" includeLocation="true"> <logger name="com.fasterxml" level="trace"/>
<root level="debug" includeLocation="true">
<appender-ref ref="rolling"/> <appender-ref ref="rolling"/>
</root> </root>
</loggers> </loggers>

View File

@ -0,0 +1,32 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# --------------------------------------------------------------------
# Email Settings
# The subject line for the email message.
email.validation.subject=Welcome to Archiva
# Feedback page
email.feedback.path=http://archiva.apache.org/mail-lists.html
email.url.path=index.html
rest.csrffilter.enabled=false