1 Commits

Author SHA1 Message Date
Willem Dantuma
8667001c01 Remove oauth 2026-03-25 21:08:18 +01:00
26 changed files with 85 additions and 2780 deletions

37
package-lock.json generated
View File

@@ -27,7 +27,6 @@
"@ngrx/router-store": "^21.0.1",
"@ngrx/store": "^21.0.1",
"@popperjs/core": "2.11.8",
"angular-oauth2-oidc": "^20.0.2",
"assert": "^2.1.0",
"bootstrap": "^5.3.8",
"browserify-zlib": "^0.2.0",
@@ -83,32 +82,31 @@
},
"dist/common": {
"name": "@farmmaps/common",
"version": "4.22.0-prerelease.2619",
"version": "2.1.0",
"dependencies": {
"tslib": "^2.3.0"
},
"peerDependencies": {
"@angular/common": "21.1.0",
"@angular/core": "21.1.0",
"@angular/forms": "21.1.0",
"@microsoft/signalr": "10.0.0",
"@angular/common": "^21.1.0",
"@angular/core": "^21.1.0",
"@angular/forms": "^21.1.0",
"@microsoft/signalr": "^10.0.0",
"@ng-bootstrap/ng-bootstrap": "^20.0.0",
"@ngrx/effects": "21.0.1",
"@ngrx/router-store": "21.0.1",
"@ngrx/store": "21.0.1",
"angular-oauth2-oidc": "20.0.2",
"@ngrx/effects": "^21.0.1",
"@ngrx/router-store": "^21.0.1",
"@ngrx/store": "^21.0.1",
"bootstrap": "^5.3.3",
"moment": "^2.29.4",
"ngx-avatars": "1.10.1",
"ngx-avatars": "^1.10.1",
"ngx-clipboard": "^16.0.0",
"ngx-image-cropper": "^7.0.0",
"ngx-uploadx": "7.0.1",
"ngx-uploadx": "^7.0.1",
"tassign": "^1.0.0"
}
},
"dist/common-map": {
"name": "@farmmaps/common-map",
"version": "4.22.0-prerelease.2620",
"version": "2.0.0",
"dependencies": {
"tslib": "^2.0.0"
},
@@ -8897,19 +8895,6 @@
"node": ">= 14.0.0"
}
},
"node_modules/angular-oauth2-oidc": {
"version": "20.0.2",
"resolved": "https://registry.npmjs.org/angular-oauth2-oidc/-/angular-oauth2-oidc-20.0.2.tgz",
"integrity": "sha512-bMSXEQIuvgq8yqnsIatZggAvCJvY+pm7G8MK0tWCHR93UpFuNN+L5B6pY9CzRg8Ys+VVhkLIBx4zEHbJnv9icg==",
"license": "MIT",
"dependencies": {
"tslib": "^2.5.2"
},
"peerDependencies": {
"@angular/common": ">=20.0.0",
"@angular/core": ">=20.0.0"
}
},
"node_modules/ansi-colors": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz",

View File

@@ -30,7 +30,6 @@
"@ngrx/router-store": "^21.0.1",
"@ngrx/store": "^21.0.1",
"@popperjs/core": "2.11.8",
"angular-oauth2-oidc": "^20.0.2",
"assert": "^2.1.0",
"bootstrap": "^5.3.8",
"browserify-zlib": "^0.2.0",

File diff suppressed because it is too large Load Diff

View File

@@ -16,7 +16,6 @@
"bootstrap": "^5.3.3",
"@microsoft/signalr": "^10.0.0",
"ngx-uploadx": "^7.0.1",
"angular-oauth2-oidc": "^20.0.2",
"moment": "^2.29.4",
"ngx-avatars": "^1.10.1",
"ngx-image-cropper": "^7.0.0",

View File

@@ -4,7 +4,7 @@ import { IItemTypes } from '../models/item.types';
import { IListItem } from '../models/list.item';
import { IUser } from '../models/user';
import { IItem } from '../models/item';
import { UserInfo } from 'angular-oauth2-oidc';
import { UserInfo } from '../models/user';
export const INITUSER = '[AppCommon] InitUser';
export const INITUSERSUCCESS = '[AppCommon] InitUserSuccess';

View File

@@ -1,8 +1,6 @@
import {NgModule} from '@angular/core';
import {RouterModule} from '@angular/router';
import {AuthCallbackComponent} from './components/auth-callback/auth-callback.component';
import {AuthCallbackGuard} from './components/auth-callback/auth-callback.guard';
import {NavBarGuard} from './services/nav-bar-guard.service';
import {FullScreenGuard} from './services/full-screen-guard.service';
import {SessionClearedComponent} from './components/session-cleared/session-cleared.component';
@@ -11,10 +9,6 @@ import { ProductionGuard } from './services/production-guard.service';
const routes = [
{
path: 'cb',
component: AuthCallbackComponent
},
{
path: 'loggedout',
component: SessionClearedComponent,

View File

@@ -3,9 +3,6 @@ import { NgModule, ModuleWithProviders, Injector, Optional, SkipSelf, inject, pr
import { DatePipe } from '@angular/common';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
// external modules
import { OAuthModule, OAuthService, OAuthStorage } from 'angular-oauth2-oidc';
//components
import { ItemTypeService } from './services/itemtype.service';
@@ -23,16 +20,13 @@ import { DownloadService } from './services/download.service';
import { GeolocatorService } from './services/geolocator.service';
import { WeatherService} from './services/weather.service';
import { AppConfig } from './shared/app.config';
import { AccessTokenInterceptor } from "./shared/accesstoken.interceptor";
import { appConfigFactory } from "./shared/app.config.factory";
import { AuthGuard } from './services/auth-guard.service';
import { NavBarGuard } from './services/nav-bar-guard.service';
import { PackageGuard } from './services/package-guard.service';
import { FullScreenGuard } from './services/full-screen-guard.service';
import { AuthCallbackGuard } from './components/auth-callback/auth-callback.guard';
import { ResumableFileUploadService } from './components/resumable-file-upload/resumable-file-upload.service';
import { NgbDateNativeAdapter } from './services/date-adapter.service'
import { AuthConfigFactory } from './shared/authconfigFactory';
import { StateSerializerService } from './services/state-serializer.service';
import { PackageService } from './services/package.service';
import { PackagePreloadStrategy } from './services/package-preload-strategy.service';
@@ -58,12 +52,10 @@ export {
GeolocatorService,
WeatherService,
AppConfig,
AccessTokenInterceptor,
AuthGuard,
NavBarGuard,
PackageGuard,
FullScreenGuard,
AuthCallbackGuard,
ResumableFileUploadService,
NgbDateNativeAdapter,
StateSerializerService,
@@ -79,9 +71,6 @@ export {
};
@NgModule({
imports: [
OAuthModule.forRoot(),
]
})
export class AppCommonServiceModule {
constructor(@Optional() @SkipSelf() parentModule: AppCommonServiceModule) {
@@ -97,14 +86,9 @@ export class AppCommonServiceModule {
AppConfig,
ItemTypeService,
provideAppInitializer(() => {
const initializerFn = (appConfigFactory)(inject(Injector), inject(AppConfig), inject(OAuthService), inject(AuthConfigFactory), inject(OAuthStorage), inject(ItemTypeService));
const initializerFn = (appConfigFactory)(inject(Injector), inject(AppConfig), inject(ItemTypeService));
return initializerFn();
}),
{
provide: HTTP_INTERCEPTORS,
useClass: AccessTokenInterceptor,
multi: true
},
DatePipe
]
};

View File

@@ -8,7 +8,6 @@ import { FormsModule } from '@angular/forms';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { EffectsModule } from '@ngrx/effects';
import { StoreModule } from '@ngrx/store';
import { OAuthModule } from 'angular-oauth2-oidc';
import { ClipboardModule } from 'ngx-clipboard';
import { UploadxModule } from 'ngx-uploadx';
@@ -24,7 +23,6 @@ import { ImageCropperModule } from 'ngx-image-cropper';
import * as commonActions from './actions/app-common.actions';
import { AppMenuComponent } from './components/app-menu/app-menu.component';
import { AppComponent } from './components/app/app.component';
import { AuthCallbackComponent } from './components/auth-callback/auth-callback.component';
import { AvatarComponent } from './components/avatar/avatar.component';
import { BackButtonComponent } from './components/back-button/back-button.component';
import { EditImageModalComponent } from './components/edit-image-modal/edit-image-modal.component';
@@ -71,25 +69,22 @@ import { IUrlType } from './models/url.type';
import { IUser } from './models/user';
import { WeatherCurrentObservation } from './models/weatherCurrentObservation';
import * as commonReducers from './reducers/app-common.reducer';
import { AuthConfigFactory, IAuthconfigFactory } from './shared/authconfigFactory';
import { SafePipe } from './shared/safe.pipe';
import { SecureOAuthStorage } from './shared/secureOAuthStorage';
export const FM_COMMON_STARTPAGE = new InjectionToken<string>('fm-common-startpage');
export {
Alert, AppComponent, AuthCallbackComponent, AuthConfigFactory, AvatarComponent, BackButtonComponent, commonActions,
Alert, AppComponent, AvatarComponent, BackButtonComponent, commonActions,
commonReducers, EditImageModalComponent,
GradientComponent,
GradientSelectComponent, HasClaimDirective, HasPackageDirective, HasRoleDirective, IAuthconfigFactory, IColor, IDataLayer, IEventMessage, IGradientstop, IItem, IItemLinkType, IItemTask, IItemType, IItemTypes, IJsonline, IListItem, IPackage,
GradientSelectComponent, HasClaimDirective, HasPackageDirective, HasRoleDirective, IColor, IDataLayer, IEventMessage, IGradientstop, IItem, IItemLinkType, IItemTask, IItemType, IItemTypes, IJsonline, IListItem, IPackage,
IAclRights, IListItemAclRights, ISharedItem,
IPackages, IQueryState, ISenMLItem, Item, ItemLinkComponent, ItemTask, ITypeaheadItem, IUrlType, IUser, MenuBackgroundComponent, NotFoundComponent,
NotImplementedComponent, PackageExistsDirective, ResumableFileUploadComponent, SafePipe, SecureOAuthStorage, SessionClearedComponent, SidePanelComponent, TagInputComponent, ThumbnailComponent, TimespanComponent, UserMenuComponent, WeatherCurrentObservation
NotImplementedComponent, PackageExistsDirective, ResumableFileUploadComponent, SafePipe, SessionClearedComponent, SidePanelComponent, TagInputComponent, ThumbnailComponent, TimespanComponent, UserMenuComponent, WeatherCurrentObservation
};
@NgModule({ declarations: [
AppComponent,
AuthCallbackComponent,
SidePanelComponent,
SafePipe,
NotFoundComponent,
@@ -123,7 +118,6 @@ export {
CommonModule,
AppComponent,
ResumableFileUploadComponent,
AuthCallbackComponent,
SidePanelComponent,
SafePipe,
NotFoundComponent,
@@ -149,7 +143,6 @@ export {
AppCommonRoutingModule,
StoreModule.forFeature(MODULE_NAME, commonReducers.reducer),
EffectsModule.forFeature([commonEffects.AppCommonEffects]),
OAuthModule.forRoot(),
NgbModule,
FormsModule,
UploadxModule,

View File

@@ -5,7 +5,6 @@ import { Subscription, Observable } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';
import { Store, Action } from '@ngrx/store';
import { IUser } from '../../models/user';
import { OAuthService, OAuthErrorEvent } from 'angular-oauth2-oidc';
import { FM_COMMON_STARTPAGE } from '../../common.module';
//AppCommon
@@ -19,13 +18,13 @@ import { AppConfig } from '../../shared/app.config';
import * as appReducers from '../../reducers/app-common.reducer';
@Component({
selector: 'fm-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false
@Component({
selector: 'fm-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false
})
export class AppComponent implements OnInit, OnDestroy {
@@ -64,7 +63,6 @@ export class AppComponent implements OnInit, OnDestroy {
private eventService$: EventService,
private healthCheckService$: HealthCheckService,
private itemTypeService$: ItemTypeService,
private oauthService$: OAuthService,
private appConfig$: AppConfig
) {
}
@@ -121,7 +119,6 @@ export class AppComponent implements OnInit, OnDestroy {
ngOnInit() {
this.InstallRouteEventHandler();
this.InstallEventServiceEventHandler();
this.InstallAuthenticationEventHandler();
this.InstallHealthCheck();
}
@@ -139,32 +136,6 @@ export class AppComponent implements OnInit, OnDestroy {
if (this.eventSub$) this.eventSub$.unsubscribe();
}
private InstallAuthenticationEventHandler() {
// auth event handler
this.oauthService$.events.subscribe((event) => {
//console.debug(event.type);
if (event.type == 'token_error' || event.type == 'silent_refresh_timeout' || event.type == 'logout') {
const e = event as OAuthErrorEvent;
const p = e.params as any;
if (event.type == 'silent_refresh_timeout' || event.type == 'logout' || (p.error && p.error == 'login_required')) {
//console.debug("Session expired");
this.router.navigate(['loggedout'], { queryParams: { redirectTo: this.router.url } });
}
}
if (event.type == 'token_received') {
this.oauthService$.loadUserProfile();
this.store$.dispatch(new commonActions.InitUser());
}
});
if (this.oauthService$.hasValidAccessToken()) {
this.store$.dispatch(new commonActions.InitUser());
} else {
if (this.oauthService$.getRefreshToken() != null) {
this.oauthService$.refreshToken();
}
}
}
private InstallRouteEventHandler() {
const other = this;
this.routerSub$ = this.router.events.subscribe(event => {

View File

@@ -1,22 +0,0 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { OAuthService } from 'angular-oauth2-oidc';
import { Location} from '@angular/common';
@Component({
selector: 'fm-auth-callback',
template: '<div></div>',
standalone: false
})
export class AuthCallbackComponent {
constructor(private router$: Router,private oauthService$:OAuthService) {
oauthService$.loadDiscoveryDocument().then(() => {
oauthService$.tryLoginCodeFlow().then(() => {
router$.navigateByUrl((oauthService$.state && oauthService$.state!="")?decodeURIComponent(oauthService$.state):"");
}).catch(() => {
router$.navigateByUrl("/");
});
})
}
}

View File

@@ -1,17 +0,0 @@
import { Router } from '@angular/router';
import { Injectable } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
import { } from '@angular/router';
@Injectable({
providedIn: 'root',
})
export class AuthCallbackGuard {
constructor(private router$: Router,private oauthService$:OAuthService) {}
canActivate() {
this.router$.navigateByUrl(this.oauthService$.state);
return false;
}
}

View File

@@ -1,15 +1,12 @@
import { Directive, ViewContainerRef,TemplateRef,OnInit,Input,OnDestroy } from '@angular/core';
import { Directive, ViewContainerRef,TemplateRef,OnInit,Input } from '@angular/core';
import { Store} from '@ngrx/store';
import * as appCommonReducer from '../../reducers/app-common.reducer'
import { IPackages } from '../../models/package';
import { Observable, Subscription } from 'rxjs';
import { skip } from 'rxjs/operators';
import {OAuthService } from 'angular-oauth2-oidc';
import { Observable } from 'rxjs';
import { IUser } from '../../models/user';
@Directive({
selector: '[fm-hasclaim]',
standalone: false
@Directive({
selector: '[fm-hasclaim]',
standalone: false
})
export class HasClaimDirective implements OnInit{
@Input('fm-hasclaim') claim:string;

View File

@@ -1,5 +1,4 @@
import { Injectable, OnDestroy } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
import { Subject , Subscription } from 'rxjs';
import { HttpClient } from "@angular/common/http";
import { UploadxService, UploadState,UploadxOptions} from 'ngx-uploadx';
@@ -19,7 +18,7 @@ export class ResumableFileUploadService implements OnDestroy{
private _eventSub:Subscription;
private initialized = false;
constructor(private httpClient: HttpClient,private oauthService: OAuthService,private uploadService: UploadxService,public appConfig: AppConfig) {
constructor(private httpClient: HttpClient,private uploadService: UploadxService,public appConfig: AppConfig) {
}
@@ -31,7 +30,6 @@ export class ResumableFileUploadService implements OnDestroy{
if(!this.initialized) {
this._eventSub=this.uploadService.init({
endpoint:this.endPoint(),
token:() => this.oauthService.getAccessToken(),
chunkSize: 2097152}).subscribe((uploadState:UploadState) => {
this.handleState(uploadState);
} );

View File

@@ -1,5 +1,4 @@
import { Component, OnInit,Input } from '@angular/core';
import { OAuthService} from 'angular-oauth2-oidc'
import { IUser } from '../../models/user';
import {Store} from '@ngrx/store';
import * as appReducers from '../../reducers/app-common.reducer';
@@ -16,13 +15,13 @@ export class UserMenuComponent implements OnInit {
@Input() user:IUser;
@Input() showMenu:boolean;
constructor(private oauthService:OAuthService, private store: Store<appReducers.State>) { }
constructor(private store: Store<appReducers.State>) { }
ngOnInit(): void {
}
getProvider():string | null {
const ownedClaims = this.oauthService.getIdentityClaims();
const ownedClaims = [];//TODO FIX THIS
if(ownedClaims) {
if (ownedClaims["idp"] != "local") {
return ownedClaims["idp"];

View File

@@ -1,6 +1,5 @@
import { Injectable, Inject, LOCALE_ID } from '@angular/core';
import { Router } from '@angular/router';
import { OAuthService,UserInfo } from 'angular-oauth2-oidc';
import { Store } from '@ngrx/store';
import { Actions,ofType,createEffect } from '@ngrx/effects';
import { of,from,zip } from 'rxjs';
@@ -13,27 +12,13 @@ import { UserService } from '../services/user.service';
import { IItemTypes } from '../models/item.types';
import { IListItem } from '../models/list.item';
import {StateSerializerService} from '../services/state-serializer.service';
import { IUser } from '../common.module';
import { UserInfo } from '../models/user';
@Injectable()
export class AppCommonEffects {
locale: string;
login$ = createEffect(() => this.actions$.pipe(
ofType(appCommonActions.LOGIN),
withLatestFrom(this.store$.select(appCommonReducers.selectGetInitialized)),
mergeMap(([action, initialized]) => {
const a = (action as appCommonActions.Login);
this.oauthService$.initCodeFlow(a.url,{"prompt":"login"});
return [];
})),{dispatch:false});
logout$ = createEffect(() => this.actions$.pipe(
ofType(appCommonActions.LOGOUT),
mergeMap((action) => {
this.oauthService$.revokeTokenAndLogout();
return [];
})),{dispatch:false});
loadItemTypes$ = createEffect(() => this.actions$.pipe(
ofType(appCommonActions.LOADITEMTYPES),
switchMap((action) => {
@@ -43,21 +28,16 @@ export class AppCommonEffects {
}
)));
//TODO FIX THIS
initUser$ = createEffect(() => this.actions$.pipe(
ofType(appCommonActions.INITUSER),
first(),
switchMap((action) => {
return zip(this.userService$.getCurrentUser(),from(this.oauthService$.loadUserProfile())).pipe(
switchMap(([user,userInfo]) => {
if (location.hostname === 'localhost' || user.language === undefined || user.language === this.locale)
{
return of(new appCommonActions.InitUserSuccess(user,userInfo as UserInfo))
}
return of(new appCommonActions.SwitchLanguage(user.language))
}),
catchError(error => of(new appCommonActions.Fail(error))))
}
)));
let user :IUser = {claims:[],searchable:true}
let userInfo : UserInfo = {sub:"aabbccdd"}
return of(new appCommonActions.InitUserSuccess(user,userInfo))
}
)));
switchLanguage$ = createEffect(() => this.actions$.pipe(
ofType(appCommonActions.SWITCHLANGUAGE),
@@ -213,19 +193,12 @@ export class AppCommonEffects {
ofType(appCommonActions.ONLINE),
switchMap((action) => {
//console.debug("Online: Check token");
if(!this.oauthService$.hasValidAccessToken()) {
//console.debug("No valid token, try to refresh");
if(this.oauthService$.getRefreshToken() != null ) {
//console.debug("We have a refresh token");
this.oauthService$.refreshToken();
}
}
return of(undefined);
})),{dispatch:false});
constructor(private actions$: Actions, private store$: Store<appCommonReducers.State>, private oauthService$: OAuthService, private itemService$: ItemService, private folderService$:FolderService, private userService$: UserService, private router$: Router, private stateSerializerService$:StateSerializerService, @Inject(LOCALE_ID) locale: string) {
constructor(private actions$: Actions, private store$: Store<appCommonReducers.State>, private itemService$: ItemService, private folderService$:FolderService, private userService$: UserService, private router$: Router, private stateSerializerService$:StateSerializerService, @Inject(LOCALE_ID) locale: string) {
this.locale = locale;
store$.dispatch(new appCommonActions.LoadItemTypes());
}

View File

@@ -16,4 +16,9 @@ export interface IUser {
searchable: boolean;
newsletter?: boolean;
language?: string;
}
export interface UserInfo {
sub: string;
[key: string]: any;
}

View File

@@ -3,7 +3,6 @@ import { Router, Route, ActivatedRouteSnapshot, RouterStateSnapshot, UrlSegment,
import { Store } from '@ngrx/store';
import { OAuthService } from 'angular-oauth2-oidc';
import { Observable } from 'rxjs';
@@ -15,7 +14,7 @@ import * as appCommonReducer from '../reducers/app-common.reducer';
})
export class AuthGuard {
constructor(private oauthService: OAuthService, private router: Router, private store: Store<appCommonReducer.State>) { }
constructor(private router: Router, private store: Store<appCommonReducer.State>) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
//console.debug("AuthGuard->canActivate", route, state);
@@ -36,36 +35,38 @@ export class AuthGuard {
return this.checkLogin(route.path, null);
}
//TODO FIX THIS
checkLogin(url: string, route: ActivatedRouteSnapshot): boolean {
//console.debug("AuthGuard->checkLogin", url, route);
if (!this.oauthService.hasValidAccessToken()) {
//console.debug("No valid token");
this.oauthService.initCodeFlow(url);
return false;
} else {
const requiredRoleClaim = route.data.role;
if (!requiredRoleClaim) { return true; }
const ownedClaims = this.oauthService.getIdentityClaims();
if (!ownedClaims) {
//console.debug("No owned claims");
return false;
}
const ownedRoleClaims: string[] = ownedClaims['role'];
if (!ownedRoleClaims) {
// console.debug("No owned role claims");
return false;
}
if (Array.isArray(ownedRoleClaims)) {
if (ownedRoleClaims.findIndex(r => r === requiredRoleClaim) <= -1) {
//console.debug("No required role claim", ownedRoleClaims, requiredRoleClaim);
return false;
}
}
else {
if (ownedRoleClaims !== requiredRoleClaim) { console.debug("No required role claim", ownedRoleClaims, requiredRoleClaim); return false; }
}
//console.debug("Has required role claim", requiredRoleClaim);
return true;
}
// if (!this.oauthService.hasValidAccessToken()) {
// //console.debug("No valid token");
// this.oauthService.initCodeFlow(url);
// return false;
// } else {
// const requiredRoleClaim = route.data.role;
// if (!requiredRoleClaim) { return true; }
// const ownedClaims = this.oauthService.getIdentityClaims();
// if (!ownedClaims) {
// //console.debug("No owned claims");
// return false;
// }
// const ownedRoleClaims: string[] = ownedClaims['role'];
// if (!ownedRoleClaims) {
// // console.debug("No owned role claims");
// return false;
// }
// if (Array.isArray(ownedRoleClaims)) {
// if (ownedRoleClaims.findIndex(r => r === requiredRoleClaim) <= -1) {
// //console.debug("No required role claim", ownedRoleClaims, requiredRoleClaim);
// return false;
// }
// }
// else {
// if (ownedRoleClaims !== requiredRoleClaim) { console.debug("No required role claim", ownedRoleClaims, requiredRoleClaim); return false; }
// }
// //console.debug("Has required role claim", requiredRoleClaim);
// return true;
// }
return true;
}
}

View File

@@ -1,5 +1,4 @@
import { Injectable } from '@angular/core';
import { OAuthService } from 'angular-oauth2-oidc';
import { Observable, ReplaySubject, Subscription, timer } from 'rxjs';
import { catchError, take } from 'rxjs/operators';
import { IItem } from '../models/item';
@@ -12,7 +11,7 @@ export class CacheService {
private proxyCacheMap: { [key: string]: ReplaySubject<IItem[]> } = {};
private subscriptionMap: { [key: string]: Subscription } = {};
constructor(private itemService: ItemService, public oauthService: OAuthService) {
constructor(private itemService: ItemService) {
timer(0, REFRESH_INTERVAL).subscribe(() => {
this.subscriptionMap = {};
})
@@ -23,7 +22,7 @@ export class CacheService {
this.proxyCacheMap[itemType] = new ReplaySubject(1);
}
if (this.oauthService.getAccessToken() != null && !this.subscriptionMap[itemType]) {
if (!this.subscriptionMap[itemType]) {
this.subscriptionMap[itemType] = this.itemService.getItemList(itemType)
.pipe(
catchError(error => {

View File

@@ -1,7 +1,6 @@
import { Injectable } from '@angular/core';
import { IEventMessage } from '../models/event.message';
import { Subject, timer } from 'rxjs';
import { OAuthService } from 'angular-oauth2-oidc';
import { HubConnection, HubConnectionBuilder, LogLevel ,HttpTransportType,HubConnectionState} from '@microsoft/signalr';
import { AppConfig } from "../shared/app.config";
@@ -16,7 +15,7 @@ export class EventService {
private _apiEndPoint: string;
public authenticated = false;
constructor(private oauthService: OAuthService, private appConfig: AppConfig) {
constructor(private appConfig: AppConfig) {
this._apiEndPoint = appConfig.getConfig("apiEndPoint");
this._connection = new HubConnectionBuilder().withUrl(`${ this._apiEndPoint}/eventHub`,
{ transport: HttpTransportType.WebSockets,
@@ -41,17 +40,9 @@ export class EventService {
});
}
private Authenticate() {
const accessToken = this.oauthService.getAccessToken();
if (this.oauthService.hasValidAccessToken()) {
this._connection.send('authenticate', this.oauthService.getAccessToken());
private Authenticate() { //TODO FIX THIS
this._connection.send('authenticate', "token");
this.authenticated=true;
} else {
//try again after half a second
setTimeout(() => {
this.Authenticate();
}, 800);
}
}
Stop() {

View File

@@ -1,40 +0,0 @@
import { Injectable, Injector, Inject, DOCUMENT } from '@angular/core';
import { AppConfig } from "./app.config";
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { OAuthService } from 'angular-oauth2-oidc';
import { Observable } from 'rxjs';
@Injectable()
export class AccessTokenInterceptor implements HttpInterceptor {
private oauthService: OAuthService = null;
private audience: string[] = [];
private base: string;
constructor(private injector: Injector, private appConfig: AppConfig, @Inject(DOCUMENT) private document: any) {
this.base = document.location.href;
}
hasAudience(url: string): boolean {
const u = new URL(url,this.base);
for (const audience of this.audience) {
if (u.href.startsWith(audience)) return true;
}
return false;
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.oauthService && this.hasAudience(request.url)) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${this.oauthService.getAccessToken()}`
}
});
} else {
this.oauthService = this.injector.get(OAuthService, null);
if(this.oauthService && this.oauthService.issuer) this.audience = (this.appConfig.getConfig("audience") as string).split(",");
}
return next.handle(request);
}
}

View File

@@ -1,23 +1,15 @@
import { Injector } from '@angular/core';
import { Location} from '@angular/common';
import { Router,UrlSerializer } from '@angular/router';
import { AuthConfig, OAuthService, OAuthErrorEvent, OAuthStorage } from 'angular-oauth2-oidc';
import { AppConfig } from "./app.config";
import {ItemTypeService} from '../services/itemtype.service';
import { IAuthconfigFactory } from './authconfigFactory';
export function appConfigFactory(injector:Injector, appConfig: AppConfig, oauthService: OAuthService, authconfigFactory:IAuthconfigFactory,authStorage:OAuthStorage,itemtypeService:ItemTypeService): () => Promise<any> {
export function appConfigFactory(injector:Injector, appConfig: AppConfig, itemtypeService:ItemTypeService): () => Promise<any> {
return (): Promise<any> => {
return new Promise<void>((resolve,reject) => {
appConfig.load().then(() => {
itemtypeService.load(appConfig);
oauthService.configure(authconfigFactory.getAuthConfig(appConfig));
oauthService.setStorage(authStorage);
oauthService.setupAutomaticSilentRefresh();
}).then(() => oauthService.loadDiscoveryDocument()
).then(() => resolve()).catch(() => reject());
}).then(() => resolve()).catch(() => reject());
});
}
}

View File

@@ -1,22 +0,0 @@
import { AuthConfig } from 'angular-oauth2-oidc';
import {AppConfig} from './app.config';
export interface IAuthconfigFactory {
getAuthConfig(appConfig: AppConfig): AuthConfig;
}
export class AuthConfigFactory implements IAuthconfigFactory {
getAuthConfig(appConfig: AppConfig): AuthConfig {
const authConfig: AuthConfig = new AuthConfig();
authConfig.issuer = appConfig.getConfig("issuer");
authConfig.redirectUri = window.location.origin + "/cb";
authConfig.silentRefreshRedirectUri = window.location.origin + "/silent-refresh.html";
authConfig.clientId = appConfig.getConfig("clientId");
authConfig.customQueryParams = { audience: appConfig.getConfig("audience") };
authConfig.scope = "openid profile email";
authConfig.oidc = true;
authConfig.disableAtHashCheck = true;
authConfig.requireHttps = appConfig.getConfig("requireHttps");
return authConfig;
}
}

View File

@@ -1,36 +0,0 @@
import {OAuthStorage} from 'angular-oauth2-oidc';
import {Inject, Injectable} from '@angular/core';
@Injectable()
export class SecureOAuthStorage extends OAuthStorage {
private storage = {};
secureKey(key:string): boolean {
if(key == "nonce") return false;
if(key == "PKCI_verifier") return false;
return true;
}
getItem(key: string): string {
if(this.secureKey(key)) {
return this.storage[key];
} else {
return window.sessionStorage.getItem(key);
}
}
removeItem(key: string): void {
if(this.secureKey(key)) {
delete this.storage[key];
} else {
window.sessionStorage.removeItem(key);
}
}
setItem(key: string, data: string): void {
if(this.secureKey(key)) {
this.storage[key]=data;
} else {
window.sessionStorage.setItem(key,data);
}
}
}

View File

@@ -6,7 +6,7 @@ import {
} from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppCommonModule,AppCommonServiceModule,AuthConfigFactory,FM_COMMON_STARTPAGE } from '@farmmaps/common';
import { AppCommonModule,AppCommonServiceModule,FM_COMMON_STARTPAGE } from '@farmmaps/common';
import {AppRootComponent} from './app.component';
@@ -18,8 +18,6 @@ import {AppRoutingModule} from './app-routing.module';
import { LogoComponent } from './logo/logo.component';
import { MenuComponent } from './menu/menu.component';
import {RegisterDeviceComponent} from './registerdevice/registerdevice.component';
import { SecureOAuthStorage} from '@farmmaps/common';
import { OAuthStorage } from 'angular-oauth2-oidc';
import {Id4AuthconfigFactory} from './id4AuthconfigFactory';
import { TestComponent } from './test/test.component';
import { LandingpageComponent } from './landingpage/landingpage.component';
@@ -85,11 +83,6 @@ export const metaReducers: MetaReducer<any>[] = [debug];
EffectsModule.forRoot([]),
],
providers: [
AuthConfigFactory,
{
provide:AuthConfigFactory,
useClass:Id4AuthconfigFactory
},
{
provide: FM_COMMON_STARTPAGE,
useValue: '/map'

View File

@@ -1,23 +0,0 @@
import { IAuthconfigFactory, AppConfig } from '@farmmaps/common';
import { AuthConfig } from 'angular-oauth2-oidc';
import { Injectable } from "@angular/core";
@Injectable()
export class Id4AuthconfigFactory implements IAuthconfigFactory {
constructor() {
}
getAuthConfig(appConfig: AppConfig): AuthConfig {
const authConfig: AuthConfig = new AuthConfig();
authConfig.issuer = appConfig.getConfig("issuer");
authConfig.redirectUri = window.location.origin + "/cb";
authConfig.clientId = appConfig.getConfig("clientId");
authConfig.customQueryParams = { audience: appConfig.getConfig("audience") };
authConfig.scope = "openid profile api offline_access";
authConfig.disableAtHashCheck = true;
authConfig.responseType = "code";
authConfig.requireHttps = appConfig.getConfig("requireHttps");
return authConfig;
}
}

View File

@@ -1,22 +0,0 @@
import {IAuthconfigFactory,AppConfig} from '@farmmaps/common';
import {AuthConfig} from 'angular-oauth2-oidc';
export class LocalAuthconfigFactory implements IAuthconfigFactory {
getAuthConfig(appConfig:AppConfig): AuthConfig {
const authConfig: AuthConfig = new AuthConfig();
authConfig.issuer = appConfig.getConfig("issuer");
authConfig.redirectUri = window.location.origin + "/cb";
authConfig.silentRefreshRedirectUri = window.location.origin + "/silent-refresh.html";
authConfig.clientId = appConfig.getConfig("clientId");
authConfig.customQueryParams = { audience: appConfig.getConfig("audience") };
authConfig.scope = "openid profile email";
authConfig.oidc = true;
authConfig.disableAtHashCheck = true;
authConfig.openUri = uri => {
window.alert("OK "+uri);
}
authConfig.requireHttps = appConfig.getConfig("requireHttps");
return authConfig;
}
}