From 455e69fa00c199cb75a9ed0e213000c62fc0469d Mon Sep 17 00:00:00 2001 From: saravankumarpa Date: Mon, 17 Feb 2020 10:31:19 -0800 Subject: [PATCH 001/589] adding login WIP --- package-lock.json | 10 +++ package.json | 4 +- src/app/app.module.ts | 18 +++- .../getting-started3.component.html | 2 + .../getting-started3.component.ts | 12 ++- src/app/services/keycloak.service.spec.ts | 12 +++ src/app/services/keycloak.service.ts | 83 +++++++++++++++++++ src/index.html | 1 + src/typings.d.ts | 1 + tsconfig.json | 1 + 10 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 src/app/services/keycloak.service.spec.ts create mode 100644 src/app/services/keycloak.service.ts create mode 100644 src/typings.d.ts diff --git a/package-lock.json b/package-lock.json index 9bb8426c..75962e86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6141,6 +6141,11 @@ } } }, + "jwt-decode": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz", + "integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk=" + }, "karma": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/karma/-/karma-3.1.4.tgz", @@ -6235,6 +6240,11 @@ "source-map-support": "^0.5.5" } }, + "keycloak-js": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/keycloak-js/-/keycloak-js-4.8.3.tgz", + "integrity": "sha512-TXoZdoOYu2ScYs58L95/xSYjsTto9KRvZ+vt6mv4Dyf4pYhYZSgwMPnmi128qj/z8sm4mL1Z8nncR6XdWgNKMQ==" + }, "killable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", diff --git a/package.json b/package.json index 955a3a05..defa8c15 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,8 @@ "@fortawesome/free-solid-svg-icons": "^5.7.2", "bootstrap": "^4.2.1", "core-js": "^2.5.4", + "jwt-decode": "^2.2.0", + "keycloak-js": "^4.5.0", "ng-pick-datetime": "^7.0.0", "ngx-webstorage": "^3.0.0-beta.14", "rxjs": "~6.3.3", @@ -45,7 +47,7 @@ "@angular/language-service": "~7.2.0", "@types/jasmine": "~2.8.8", "@types/jasminewd2": "~2.0.3", - "@types/node": "~8.9.4", + "@types/node": "^8.9.5", "codelyzer": "~4.5.0", "concurrently": "^4.1.0", "http-server": "^0.11.1", diff --git a/src/app/app.module.ts b/src/app/app.module.ts index c6710b99..5fb2c72d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,6 +1,6 @@ import { BrowserModule } from '@angular/platform-browser'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; -import { NgModule } from '@angular/core'; +import {APP_INITIALIZER, NgModule} from '@angular/core'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -13,6 +13,14 @@ import { ServicesModule } from './services/services.module'; import { RouteComponentsModule } from './route-components/route-components.module'; import { FooterComponent } from './footer/footer.component'; import { ReactiveFormsModule } from '@angular/forms'; +import {KeycloakService} from './services/keycloak.service'; + +export function kcFactory(keycloakService: KeycloakService) { + return () => { + console.log('HELO WORLD---------') ; + keycloakService.init(); + }; +} @NgModule({ declarations: [ @@ -32,7 +40,13 @@ import { ReactiveFormsModule } from '@angular/forms'; ReactiveFormsModule ], providers: [ - TransomApiClientService + TransomApiClientService, + { + provide: APP_INITIALIZER, + useFactory: kcFactory, + deps: [KeycloakService], + multi: true + } ], bootstrap: [AppComponent, FooterComponent] }) diff --git a/src/app/route-components/getting-started3/getting-started3.component.html b/src/app/route-components/getting-started3/getting-started3.component.html index 104bacb1..2209d7c8 100644 --- a/src/app/route-components/getting-started3/getting-started3.component.html +++ b/src/app/route-components/getting-started3/getting-started3.component.html @@ -6,6 +6,8 @@ >

What type of information are you looking for?

+ HELO {{token}}{{firstName}} +
diff --git a/src/app/route-components/getting-started3/getting-started3.component.ts b/src/app/route-components/getting-started3/getting-started3.component.ts index 41d6117c..eb1919f3 100644 --- a/src/app/route-components/getting-started3/getting-started3.component.ts +++ b/src/app/route-components/getting-started3/getting-started3.component.ts @@ -3,6 +3,7 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { FormBuilder, Validators } from '@angular/forms'; import { DataService } from 'src/app/services/data.service'; +import {KeycloakService} from '../../services/keycloak.service'; @Component({ templateUrl: './getting-started3.component.html', @@ -16,13 +17,18 @@ export class GettingStarted3Component implements OnInit { foiRequest: FoiRequest; targetKey: string = 'requestType'; + token = ''; + firstName = '' - constructor(private fb: FormBuilder, private dataService: DataService) {} + constructor(private fb: FormBuilder, private dataService: DataService, private keyclokservice: KeycloakService) {} ngOnInit() { // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + console.log('TOKEN:', this.keyclokservice.getToken()) + this.token = this.keyclokservice.getToken(); + this.firstName = this.keyclokservice.getFirstName(); } doContinue() { @@ -34,6 +40,10 @@ export class GettingStarted3Component implements OnInit { ); this.base.goFoiForward(state.requestData[this.targetKey].requestType); } + onClickMe() { + console.log('saying hello') + this.keyclokservice.login() + } doGoBack() { this.base.goFoiBack(); diff --git a/src/app/services/keycloak.service.spec.ts b/src/app/services/keycloak.service.spec.ts new file mode 100644 index 00000000..5ff52559 --- /dev/null +++ b/src/app/services/keycloak.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { KeycloakService } from './keycloak.service'; + +describe('KeycloakService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: KeycloakService = TestBed.get(KeycloakService); + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts new file mode 100644 index 00000000..fa042f4d --- /dev/null +++ b/src/app/services/keycloak.service.ts @@ -0,0 +1,83 @@ +import { Injectable } from '@angular/core'; +import * as jwt_decode from 'jwt-decode'; + +declare var Keycloak: any; +let jwtDecode = require('jwt-decode'); + +@Injectable({ + providedIn: 'root' +}) +export class KeycloakService { + + private keycloakAuth: any; + + constructor() { } + + init(): Promise { + return new Promise((resolve, reject) => { + + const keycloakConfig = { + realm: 'fcf0kpqr', + url: 'https://sso-dev.pathfinder.gov.bc.ca/auth' , + clientId: 'sbc-auth-web', + credentials: { + secret: 'aeb2b9bc-672b-4574-8bc8-e76e853c37cb', + 'ssl-required': 'external', + 'public-client': true + }, + }; + if (this.keycloakAuth && this.keycloakAuth.token) { + + } + this.keycloakAuth = new Keycloak(keycloakConfig); + this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN')}) + .success(() => { + sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); + if (this.keycloakAuth.token) { + this.initUser(); + } + resolve(); + }) + .error(() => { + reject(); + }); + }); + } + + getToken(): string { + return this.keycloakAuth.token; + } + getUserName(): string { + return this.keycloakAuth.user; + } + + login(): void { + this.keycloakAuth.login({idpHint: 'bcsc' }) + .success(() => { + console.log('successs' + this.keycloakAuth.token); + }) + .error(() => { + console.log('error'); + }); + + } + + getFirstName() { + console.log('sessionStorage.getItem(\'KC_TOKEN\')',sessionStorage.getItem('KC_TOKEN'), !sessionStorage.getItem('KC_TOKEN')) + if (!sessionStorage.getItem('KC_TOKEN')) { + console.log('helo') + const decoded = jwt_decode(sessionStorage.getItem('KC_TOKEN')); + return decoded.lastname; + } else { + return ''; + } + } + + initUser(): void { + if (sessionStorage.getItem('KC_TOKEN')) { + const decoded = jwt_decode(sessionStorage.getItem('KC_TOKEN')); + console.log('this.parsedToken.lastname,' + decoded.lastname); + } + + } +} diff --git a/src/index.html b/src/index.html index 95a3f579..d0de4532 100644 --- a/src/index.html +++ b/src/index.html @@ -1,6 +1,7 @@ + FOI Request | B.C. Government diff --git a/src/typings.d.ts b/src/typings.d.ts new file mode 100644 index 00000000..97f74965 --- /dev/null +++ b/src/typings.d.ts @@ -0,0 +1 @@ +declare var require: any; diff --git a/tsconfig.json b/tsconfig.json index b271fd9f..235cc857 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ "experimentalDecorators": true, "importHelpers": true, "target": "es5", + "types": [ "node" ], "typeRoots": [ "node_modules/@types" ], From dfe95c9b63d9504936cd6487924b05034b97ad0a Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Mon, 17 Feb 2020 10:34:15 -0800 Subject: [PATCH 002/589] draft changes for route --- src/app/app-routing.module.ts | 8 ++-- .../route-components/auth/auth.component.html | 28 +++++++++++++ .../route-components/auth/auth.component.scss | 0 .../auth/auth.component.spec.ts | 25 +++++++++++ .../route-components/auth/auth.component.ts | 42 +++++++++++++++++++ .../route-components.module.ts | 2 + src/app/services/data.json | 1 + 7 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/app/route-components/auth/auth.component.html create mode 100644 src/app/route-components/auth/auth.component.scss create mode 100644 src/app/route-components/auth/auth.component.spec.ts create mode 100644 src/app/route-components/auth/auth.component.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index c9b05274..b81b9bfb 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -3,6 +3,7 @@ import { Routes, RouterModule } from '@angular/router'; import { LandingComponent } from './route-components/landing/landing.component'; import { GettingStarted1Component } from './route-components/getting-started1/getting-started1.component'; import { GettingStarted2Component } from './route-components/getting-started2/getting-started2.component'; +import { AuthComponent } from './route-components/auth/auth.component'; import { GettingStarted3Component } from './route-components/getting-started3/getting-started3.component'; import { GeneralInfoComponent } from './route-components/general-info/general-info.component'; import { MinistryConfirmationComponent } from './route-components/ministry-confirmation/ministry-confirmation.component'; @@ -23,8 +24,9 @@ const routes: Routes = [ { path: '', component: LandingComponent }, { path: 'getting-started1', component: GettingStarted1Component }, { path: 'getting-started2', component: GettingStarted2Component }, + { path: 'auth', component: AuthComponent }, { path: 'getting-started3', component: GettingStarted3Component }, - + // General { path: 'general/fee-info', component: GeneralInfoComponent }, { path: 'general/ministry-confirmation', component: MinistryConfirmationComponent }, @@ -46,7 +48,7 @@ const routes: Routes = [ { path: 'personal/contact-info-options', component: ContactInfoOptionsComponent }, { path: 'personal/review-submit', component: ReviewSubmitComponent }, { path: 'personal/submit-complete', component: ReviewSubmitCompleteComponent}, - + // Personal / Child { path: 'personal/child/proof-of-guardianship', component: ProofOfGuardianshipComponent }, { path: 'personal/child/child-information', component: ChildInformationComponent }, @@ -120,7 +122,7 @@ const routes: Routes = [ { path: 'personal/yourself-child-another/contact-info-options', component: ContactInfoOptionsComponent }, { path: 'personal/yourself-child-another/review-submit', component: ReviewSubmitComponent }, { path: 'personal/yourself-child-another/submit-complete', component: ReviewSubmitCompleteComponent}, - + // Include routing for a 404 routing back to the landing page! { path: '**', redirectTo: '' } ]; diff --git a/src/app/route-components/auth/auth.component.html b/src/app/route-components/auth/auth.component.html new file mode 100644 index 00000000..76a98c8a --- /dev/null +++ b/src/app/route-components/auth/auth.component.html @@ -0,0 +1,28 @@ + +
+

Prove your identity by logging in with BC Services Card

+ +
+ +
+

+ or +

+
+ +
+ +
+ +
diff --git a/src/app/route-components/auth/auth.component.scss b/src/app/route-components/auth/auth.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/route-components/auth/auth.component.spec.ts b/src/app/route-components/auth/auth.component.spec.ts new file mode 100644 index 00000000..884576c8 --- /dev/null +++ b/src/app/route-components/auth/auth.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { AuthComponent } from './auth.component'; + +describe('AuthComponent', () => { + let component: AuthComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ AuthComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(AuthComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/route-components/auth/auth.component.ts b/src/app/route-components/auth/auth.component.ts new file mode 100644 index 00000000..b510deb8 --- /dev/null +++ b/src/app/route-components/auth/auth.component.ts @@ -0,0 +1,42 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { BaseComponent } from 'src/app/utils-components/base/base.component'; +import { FoiRequest } from 'src/app/models/FoiRequest'; +import { FormBuilder, Validators } from '@angular/forms'; +import { DataService } from 'src/app/services/data.service'; + +@Component({ + templateUrl: './auth.component.html', + styleUrls: ['./auth.component.scss'] +}) +export class AuthComponent implements OnInit { + @ViewChild(BaseComponent) base: BaseComponent; + foiForm = this.fb.group({ + auth: [null, [Validators.required]] + }); + + foiRequest: FoiRequest; + targetKey: string = 'auth'; + + constructor(private fb: FormBuilder, private dataService: DataService) {} + + ngOnInit() { + // Load the current values & populate the FormGroup. + this.foiRequest = this.dataService.getCurrentState(this.targetKey); + this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + } + + doContinue() { + // Update save data & proceed. + const state = this.dataService.setCurrentState( + this.foiRequest, + this.targetKey, + this.foiForm + ); + this.base.goFoiForward(state.requestData[this.targetKey].auth); + } + + doGoBack() { + this.base.goFoiBack(); + } + +} diff --git a/src/app/route-components/route-components.module.ts b/src/app/route-components/route-components.module.ts index fc228fea..bba35a71 100644 --- a/src/app/route-components/route-components.module.ts +++ b/src/app/route-components/route-components.module.ts @@ -6,6 +6,7 @@ import { GettingStarted2Component } from './getting-started2/getting-started2.co import { ReviewSubmitCompleteComponent } from './review-submit-complete/review-submit-complete.component'; import { ReactiveFormsModule } from '@angular/forms'; import { StartRequestComponent } from './start-request/start-request.component'; +import { AuthComponent } from './auth/auth.component'; import { GettingStarted3Component } from './getting-started3/getting-started3.component'; import { GeneralInfoComponent } from './general-info/general-info.component'; import { GeneralSelectMinistryComponent } from './general-select-ministry/general-select-ministry.component'; @@ -38,6 +39,7 @@ library.add(faSpinner); GettingStarted2Component, ReviewSubmitCompleteComponent, StartRequestComponent, + AuthComponent, GettingStarted3Component, GeneralInfoComponent, GeneralInfoComponent, diff --git a/src/app/services/data.json b/src/app/services/data.json index 25b1df4b..6adb20f0 100644 --- a/src/app/services/data.json +++ b/src/app/services/data.json @@ -112,6 +112,7 @@ { "route": "", "progress": 0 }, { "route": "getting-started1", "progress": 1 }, { "route": "getting-started2", "progress": 1 }, + { "route": "auth", "progress": 1 }, { "route": "getting-started3", "progress": 2, From eb51ac7d0bf71df5198b4523309346db4cd139dd Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Mon, 17 Feb 2020 11:58:39 -0800 Subject: [PATCH 003/589] KC integration changes --- src/app/app.module.ts | 11 +--- .../getting-started3.component.ts | 3 - .../verify-your-identity.component.ts | 12 +++- src/app/services/keycloak-config.json | 10 +++ src/app/services/keycloak.service.ts | 61 +++++++------------ tsconfig.json | 1 + 6 files changed, 45 insertions(+), 53 deletions(-) create mode 100644 src/app/services/keycloak-config.json diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5fb2c72d..4a2f853f 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -13,14 +13,7 @@ import { ServicesModule } from './services/services.module'; import { RouteComponentsModule } from './route-components/route-components.module'; import { FooterComponent } from './footer/footer.component'; import { ReactiveFormsModule } from '@angular/forms'; -import {KeycloakService} from './services/keycloak.service'; - -export function kcFactory(keycloakService: KeycloakService) { - return () => { - console.log('HELO WORLD---------') ; - keycloakService.init(); - }; -} +import { KeycloakService, KeyCloakFactory } from './services/keycloak.service'; @NgModule({ declarations: [ @@ -43,7 +36,7 @@ export function kcFactory(keycloakService: KeycloakService) { TransomApiClientService, { provide: APP_INITIALIZER, - useFactory: kcFactory, + useFactory: KeyCloakFactory, deps: [KeycloakService], multi: true } diff --git a/src/app/route-components/getting-started3/getting-started3.component.ts b/src/app/route-components/getting-started3/getting-started3.component.ts index eb1919f3..c8937957 100644 --- a/src/app/route-components/getting-started3/getting-started3.component.ts +++ b/src/app/route-components/getting-started3/getting-started3.component.ts @@ -26,9 +26,6 @@ export class GettingStarted3Component implements OnInit { // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); - console.log('TOKEN:', this.keyclokservice.getToken()) - this.token = this.keyclokservice.getToken(); - this.firstName = this.keyclokservice.getFirstName(); } doContinue() { diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts index b5c857f6..dfb87e6f 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts @@ -3,6 +3,7 @@ import { BaseComponent } from "src/app/utils-components/base/base.component"; import { Validators, FormBuilder, FormGroup, FormControl } from "@angular/forms"; import { FoiRequest } from "src/app/models/FoiRequest"; import { DataService } from "src/app/services/data.service"; +import { KeycloakService } from '../../services/keycloak.service'; @Component({ templateUrl: "./verify-your-identity.component.html", @@ -15,16 +16,19 @@ export class VerifyYourIdentityComponent implements OnInit { targetKey: string = "contactInfo"; infoBlock: string; includeBirthDate: boolean = false; + decodedToken: any; foiForm: FormGroup; - constructor(private fb: FormBuilder, private dataService: DataService) {} + constructor(private fb: FormBuilder, private dataService: DataService, private keycloak: KeycloakService) {} ngOnInit() { + let token = this.keycloak.getDecodedToken(); + console.log('token') this.foiForm = this.fb.group({ - firstName: [null, Validators.compose([Validators.required, Validators.maxLength(255)])], + firstName: [token.firstname, Validators.compose([Validators.required, Validators.maxLength(255)])], middleName: [null, [Validators.maxLength(255)]], - lastName: [null, Validators.compose([Validators.required, Validators.maxLength(255)])], + lastName: [token.lastname, Validators.compose([Validators.required, Validators.maxLength(255)])], birthDate: [null], alsoKnownAs: [null, Validators.compose([Validators.maxLength(255)])], businessName: [null, [Validators.maxLength(255)]] @@ -59,4 +63,6 @@ export class VerifyYourIdentityComponent implements OnInit { doGoBack() { this.base.goFoiBack(); } + + } diff --git a/src/app/services/keycloak-config.json b/src/app/services/keycloak-config.json new file mode 100644 index 00000000..5e301177 --- /dev/null +++ b/src/app/services/keycloak-config.json @@ -0,0 +1,10 @@ +{ + "realm": "fcf0kpqr", + "url": "https://sso-dev.pathfinder.gov.bc.ca/auth", + "clientId": "sbc-auth-web", + "credentials": { + "secret": "aeb2b9bc-672b-4574-8bc8-e76e853c37cb", + "ssl-required": "external", + "public-client": true + } +} diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index fa042f4d..fadf5d77 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -1,8 +1,15 @@ import { Injectable } from '@angular/core'; import * as jwt_decode from 'jwt-decode'; +import { default as config } from "./keycloak-config.json"; +// import KeyCloak from 'keycloak-js' declare var Keycloak: any; -let jwtDecode = require('jwt-decode'); + +export function KeyCloakFactory(keycloakService: KeycloakService) { + return () => { + keycloakService.init(); + }; +} @Injectable({ providedIn: 'root' @@ -15,22 +22,8 @@ export class KeycloakService { init(): Promise { return new Promise((resolve, reject) => { - - const keycloakConfig = { - realm: 'fcf0kpqr', - url: 'https://sso-dev.pathfinder.gov.bc.ca/auth' , - clientId: 'sbc-auth-web', - credentials: { - secret: 'aeb2b9bc-672b-4574-8bc8-e76e853c37cb', - 'ssl-required': 'external', - 'public-client': true - }, - }; - if (this.keycloakAuth && this.keycloakAuth.token) { - - } - this.keycloakAuth = new Keycloak(keycloakConfig); - this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN')}) + this.keycloakAuth = new Keycloak(config); + this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'check-sso'}) .success(() => { sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); if (this.keycloakAuth.token) { @@ -52,32 +45,24 @@ export class KeycloakService { } login(): void { - this.keycloakAuth.login({idpHint: 'bcsc' }) - .success(() => { - console.log('successs' + this.keycloakAuth.token); - }) - .error(() => { - console.log('error'); - }); - - } - - getFirstName() { - console.log('sessionStorage.getItem(\'KC_TOKEN\')',sessionStorage.getItem('KC_TOKEN'), !sessionStorage.getItem('KC_TOKEN')) - if (!sessionStorage.getItem('KC_TOKEN')) { - console.log('helo') - const decoded = jwt_decode(sessionStorage.getItem('KC_TOKEN')); - return decoded.lastname; - } else { - return ''; - } + this.keycloakAuth.login({idpHint: 'bcsc'}) } initUser(): void { if (sessionStorage.getItem('KC_TOKEN')) { - const decoded = jwt_decode(sessionStorage.getItem('KC_TOKEN')); - console.log('this.parsedToken.lastname,' + decoded.lastname); + const decoded = jwt_decode(sessionStorage.getItem('KC_TOKEN')); + console.log('this.parsedToken ,' + JSON.stringify(decoded)); } + } + getDecodedToken(): any { + console.log(sessionStorage.getItem('KC_TOKEN')) + return sessionStorage.getItem('KC_TOKEN') ? + jwt_decode(sessionStorage.getItem('KC_TOKEN')) : + { + 'firstname': null, + 'lastname': null + } } + } diff --git a/tsconfig.json b/tsconfig.json index 235cc857..16c37ad1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,7 @@ "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, "importHelpers": true, "target": "es5", "types": [ "node" ], From 80d27d9737eaa3804304838ae9cb86413ee981bc Mon Sep 17 00:00:00 2001 From: saravankumarpa Date: Mon, 17 Feb 2020 11:59:38 -0800 Subject: [PATCH 004/589] adding login WIP --- .../route-components/auth/auth.component.html | 32 +++++++------ .../route-components/auth/auth.component.ts | 48 ++++++++++++------- .../proof-of-guardianship.component.ts | 2 +- src/app/services/data.json | 2 +- .../utils-components/base/base.component.html | 2 + .../utils-components/base/base.component.ts | 1 + 6 files changed, 54 insertions(+), 33 deletions(-) diff --git a/src/app/route-components/auth/auth.component.html b/src/app/route-components/auth/auth.component.html index 76a98c8a..73c9952b 100644 --- a/src/app/route-components/auth/auth.component.html +++ b/src/app/route-components/auth/auth.component.html @@ -1,28 +1,30 @@ - -
-

Prove your identity by logging in with BC Services Card

+ + +
+

+ To avail documents online , please use your BC Service card to verify your identity.You will be sharing your first name , last name , email with us when you login with BC Service Card +

+

Do you Want to login with BC Service Card?

-

- or -

+
+ + Without BC Service card verification , the person has to walk into the office and verify the idenity. the information wont be delivered online + +
+
diff --git a/src/app/route-components/auth/auth.component.ts b/src/app/route-components/auth/auth.component.ts index b510deb8..d819523c 100644 --- a/src/app/route-components/auth/auth.component.ts +++ b/src/app/route-components/auth/auth.component.ts @@ -3,6 +3,7 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { FormBuilder, Validators } from '@angular/forms'; import { DataService } from 'src/app/services/data.service'; +import {startWith} from "rxjs/operators"; @Component({ templateUrl: './auth.component.html', @@ -11,32 +12,47 @@ import { DataService } from 'src/app/services/data.service'; export class AuthComponent implements OnInit { @ViewChild(BaseComponent) base: BaseComponent; foiForm = this.fb.group({ - auth: [null, [Validators.required]] + answerYes: [null, [Validators.required]] }); - foiRequest: FoiRequest; - targetKey: string = 'auth'; - + answerYes: boolean = null; + answerReceived: boolean; + continuetext = 'Start your request' + targetKey: string; constructor(private fb: FormBuilder, private dataService: DataService) {} + ngOnInit() { - // Load the current values & populate the FormGroup. - this.foiRequest = this.dataService.getCurrentState(this.targetKey); - this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); - } + this.base.getFoiRouteData().subscribe(data => { + if (data) { + // Load the current values & populate the FormGroup. + this.foiRequest = this.dataService.getCurrentState(this.targetKey); + const initialValues = this.foiRequest.requestData[this.targetKey]; + this.foiForm.patchValue(initialValues); + this.foiForm.valueChanges.pipe(startWith(initialValues)).subscribe(newValue => { + this.answerReceived = this.answerYes !== null; + this.answerYes = newValue.answerYes === 'true'; + if (this.answerYes) { + this.continuetext = 'Login With BC Service Card'; + } else { + this.continuetext = 'Continue without Logging In'; + } + this.base.continueDisabled = !this.answerYes; + }); + } + }); + } doContinue() { - // Update save data & proceed. - const state = this.dataService.setCurrentState( - this.foiRequest, - this.targetKey, - this.foiForm - ); - this.base.goFoiForward(state.requestData[this.targetKey].auth); + console.log('-------------try') + this.base.goFoiForward(); } - doGoBack() { this.base.goFoiBack(); } + get showAlert(): Boolean { + return this.answerReceived && !this.answerYes; + } + } diff --git a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.ts b/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.ts index fcd24193..efdb8529 100644 --- a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.ts +++ b/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.ts @@ -42,7 +42,7 @@ export class ProofOfGuardianshipComponent implements OnInit { }); } - get showAlert(): Boolean { + get showAlert(): boolean { return this.answerReceived && !this.answerYes; } diff --git a/src/app/services/data.json b/src/app/services/data.json index 6adb20f0..980825d1 100644 --- a/src/app/services/data.json +++ b/src/app/services/data.json @@ -115,7 +115,7 @@ { "route": "auth", "progress": 1 }, { "route": "getting-started3", - "progress": 2, + "progress": 3, "choices": { "general": { "routes": [ diff --git a/src/app/utils-components/base/base.component.html b/src/app/utils-components/base/base.component.html index ab12cda8..ab3b07cf 100644 --- a/src/app/utils-components/base/base.component.html +++ b/src/app/utils-components/base/base.component.html @@ -10,6 +10,8 @@ [disabled]="continueDisabled" (click)="requestGoForward()" > + + {{ continueText }}
diff --git a/src/app/utils-components/base/base.component.ts b/src/app/utils-components/base/base.component.ts index c4fe8acf..fc6033a7 100644 --- a/src/app/utils-components/base/base.component.ts +++ b/src/app/utils-components/base/base.component.ts @@ -18,6 +18,7 @@ export class BaseComponent implements OnInit { @Input("showInfo") showInfo: boolean = true; @Input("continueText") continueText: string = "Continue"; @Input("continueClass") continueClass: string = ""; + @Input("continueIcon") continueIcon: string = ""; @Input("continueDisabled") continueDisabled: boolean = false; @Input("startupComponent") startupComponent: boolean = false; routeData$: BehaviorSubject; From 568193a4ee65b1a48f3e989e721d275998a99381 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Mon, 17 Feb 2020 12:42:12 -0800 Subject: [PATCH 005/589] KC integration changes --- .../route-components/auth/auth.component.ts | 48 +++++++++++-------- .../getting-started3.component.html | 3 +- .../getting-started3.component.ts | 17 ++++--- 3 files changed, 39 insertions(+), 29 deletions(-) diff --git a/src/app/route-components/auth/auth.component.ts b/src/app/route-components/auth/auth.component.ts index d819523c..f60231f3 100644 --- a/src/app/route-components/auth/auth.component.ts +++ b/src/app/route-components/auth/auth.component.ts @@ -4,6 +4,7 @@ import { FoiRequest } from 'src/app/models/FoiRequest'; import { FormBuilder, Validators } from '@angular/forms'; import { DataService } from 'src/app/services/data.service'; import {startWith} from "rxjs/operators"; +import {KeycloakService} from '../../services/keycloak.service'; @Component({ templateUrl: './auth.component.html', @@ -19,33 +20,38 @@ export class AuthComponent implements OnInit { answerReceived: boolean; continuetext = 'Start your request' targetKey: string; - constructor(private fb: FormBuilder, private dataService: DataService) {} + constructor(private fb: FormBuilder, private dataService: DataService, private keycloakService: KeycloakService) {} ngOnInit() { - this.base.getFoiRouteData().subscribe(data => { - if (data) { - // Load the current values & populate the FormGroup. - this.foiRequest = this.dataService.getCurrentState(this.targetKey); - const initialValues = this.foiRequest.requestData[this.targetKey]; - this.foiForm.patchValue(initialValues); + console.log(sessionStorage.getItem('KC_TOKEN')); + if(sessionStorage.getItem('KC_TOKEN') !== 'undefined') { + this.base.goFoiForward(); + } else { + this.base.getFoiRouteData().subscribe(data => { + if (data) { + // Load the current values & populate the FormGroup. + this.foiRequest = this.dataService.getCurrentState(this.targetKey); + const initialValues = this.foiRequest.requestData[this.targetKey]; + this.foiForm.patchValue(initialValues); - this.foiForm.valueChanges.pipe(startWith(initialValues)).subscribe(newValue => { - this.answerReceived = this.answerYes !== null; - this.answerYes = newValue.answerYes === 'true'; - if (this.answerYes) { - this.continuetext = 'Login With BC Service Card'; - } else { - this.continuetext = 'Continue without Logging In'; - } - this.base.continueDisabled = !this.answerYes; - }); - } - }); + this.foiForm.valueChanges.pipe(startWith(initialValues)).subscribe(newValue => { + this.answerReceived = this.answerYes !== null; + this.answerYes = newValue.answerYes === 'true'; + if (this.answerYes) { + this.continuetext = 'Login With BC Service Card'; + } else { + this.continuetext = 'Continue without Logging In'; + } + this.base.continueDisabled = !this.answerYes; + }); + } + }); + } } doContinue() { - console.log('-------------try') - this.base.goFoiForward(); + this.keycloakService.login(); + // this.base.goFoiForward(); } doGoBack() { this.base.goFoiBack(); diff --git a/src/app/route-components/getting-started3/getting-started3.component.html b/src/app/route-components/getting-started3/getting-started3.component.html index 2209d7c8..4bd746c5 100644 --- a/src/app/route-components/getting-started3/getting-started3.component.html +++ b/src/app/route-components/getting-started3/getting-started3.component.html @@ -5,9 +5,8 @@ [startupComponent]="true" >
+

Welcome {{firstName}}, {{lastName}}

What type of information are you looking for?

- HELO {{token}}{{firstName}} -
diff --git a/src/app/route-components/getting-started3/getting-started3.component.ts b/src/app/route-components/getting-started3/getting-started3.component.ts index c8937957..1c706791 100644 --- a/src/app/route-components/getting-started3/getting-started3.component.ts +++ b/src/app/route-components/getting-started3/getting-started3.component.ts @@ -5,6 +5,7 @@ import { FormBuilder, Validators } from '@angular/forms'; import { DataService } from 'src/app/services/data.service'; import {KeycloakService} from '../../services/keycloak.service'; + @Component({ templateUrl: './getting-started3.component.html', styleUrls: ['./getting-started3.component.scss'] @@ -18,14 +19,22 @@ export class GettingStarted3Component implements OnInit { foiRequest: FoiRequest; targetKey: string = 'requestType'; token = ''; - firstName = '' + firstName = ''; + lastName = ''; + authenticated = false; - constructor(private fb: FormBuilder, private dataService: DataService, private keyclokservice: KeycloakService) {} + constructor(private fb: FormBuilder, private dataService: DataService, private keycloakService: KeycloakService) {} ngOnInit() { // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + if(sessionStorage.getItem('KC_TOKEN') !== 'undefined') { + let token = this.keycloakService.getDecodedToken(); + this.firstName = token.firstname; + this.lastName = token.lastname; + this.authenticated = true; + } } doContinue() { @@ -37,10 +46,6 @@ export class GettingStarted3Component implements OnInit { ); this.base.goFoiForward(state.requestData[this.targetKey].requestType); } - onClickMe() { - console.log('saying hello') - this.keyclokservice.login() - } doGoBack() { this.base.goFoiBack(); From 22800ee08f83bf9f63a49a3692f1f5e61655d7f9 Mon Sep 17 00:00:00 2001 From: saravankumarpa Date: Wed, 19 Feb 2020 23:06:42 -0800 Subject: [PATCH 006/589] Changes the routes --- src/app/services/data.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/services/data.json b/src/app/services/data.json index 980825d1..45a198f4 100644 --- a/src/app/services/data.json +++ b/src/app/services/data.json @@ -112,7 +112,6 @@ { "route": "", "progress": 0 }, { "route": "getting-started1", "progress": 1 }, { "route": "getting-started2", "progress": 1 }, - { "route": "auth", "progress": 1 }, { "route": "getting-started3", "progress": 3, @@ -133,6 +132,7 @@ }, "personal": { "routes": [ + { "route": "auth", "progress": 1 }, { "route": "personal/select-about", "progress": 2, From de062f546a4a7626d49f62cb9b12cbeb89ac57c9 Mon Sep 17 00:00:00 2001 From: saravankumarpa Date: Wed, 19 Feb 2020 23:26:37 -0800 Subject: [PATCH 007/589] once successful , redirected --- src/app/route-components/auth/auth.component.ts | 17 +++++++++++++---- src/app/services/keycloak.service.ts | 11 ++++++++++- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/app/route-components/auth/auth.component.ts b/src/app/route-components/auth/auth.component.ts index f60231f3..77896eca 100644 --- a/src/app/route-components/auth/auth.component.ts +++ b/src/app/route-components/auth/auth.component.ts @@ -25,7 +25,12 @@ export class AuthComponent implements OnInit { ngOnInit() { console.log(sessionStorage.getItem('KC_TOKEN')); - if(sessionStorage.getItem('KC_TOKEN') !== 'undefined') { + this.keycloakService.getTokenSubs().subscribe((token) => { + if (token !== 'undefined' && !!token && token.length > 1 ) { + this.base.goFoiForward(); + } + }); + if (sessionStorage.getItem('KC_TOKEN') !== 'undefined') { this.base.goFoiForward(); } else { this.base.getFoiRouteData().subscribe(data => { @@ -43,15 +48,19 @@ export class AuthComponent implements OnInit { } else { this.continuetext = 'Continue without Logging In'; } - this.base.continueDisabled = !this.answerYes; + this.base.continueDisabled = !this.answerReceived; }); } }); } } doContinue() { - this.keycloakService.login(); - // this.base.goFoiForward(); + if (this.answerYes) { + this.keycloakService.login(); + } else { + this.base.goFoiForward(); + } + // } doGoBack() { this.base.goFoiBack(); diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index fadf5d77..5b1a8f5d 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -1,6 +1,7 @@ import { Injectable } from '@angular/core'; import * as jwt_decode from 'jwt-decode'; import { default as config } from "./keycloak-config.json"; +import {BehaviorSubject, Observable} from 'rxjs'; // import KeyCloak from 'keycloak-js' declare var Keycloak: any; @@ -17,8 +18,11 @@ export function KeyCloakFactory(keycloakService: KeycloakService) { export class KeycloakService { private keycloakAuth: any; + private tokenInfo: BehaviorSubject; - constructor() { } + constructor() { + this.tokenInfo= new BehaviorSubject(''); + } init(): Promise { return new Promise((resolve, reject) => { @@ -27,6 +31,7 @@ export class KeycloakService { .success(() => { sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); if (this.keycloakAuth.token) { + this.tokenInfo.next(this.keycloakAuth.token); this.initUser(); } resolve(); @@ -48,6 +53,10 @@ export class KeycloakService { this.keycloakAuth.login({idpHint: 'bcsc'}) } + getTokenSubs(): Observable { + return this.tokenInfo.asObservable(); + } + initUser(): void { if (sessionStorage.getItem('KC_TOKEN')) { const decoded = jwt_decode(sessionStorage.getItem('KC_TOKEN')); From dd7541dcab0da4ed8abe547aea3a8bb1e7a6d189 Mon Sep 17 00:00:00 2001 From: saravankumarpa Date: Fri, 21 Feb 2020 10:45:54 -0800 Subject: [PATCH 008/589] added sidebar and disabled --- .../route-components/auth/auth.component.html | 17 ++++++++++++++--- .../verify-your-identity.component.ts | 4 ++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/app/route-components/auth/auth.component.html b/src/app/route-components/auth/auth.component.html index 73c9952b..b3dd8710 100644 --- a/src/app/route-components/auth/auth.component.html +++ b/src/app/route-components/auth/auth.component.html @@ -4,15 +4,15 @@

To avail documents online , please use your BC Service card to verify your identity.You will be sharing your first name , last name , email with us when you login with BC Service Card

-

Do you Want to login with BC Service Card?

+

Do you want to login with BC Service Card?

-
+
-
+
+ diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts index dfb87e6f..6c055d20 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts @@ -26,9 +26,9 @@ export class VerifyYourIdentityComponent implements OnInit { let token = this.keycloak.getDecodedToken(); console.log('token') this.foiForm = this.fb.group({ - firstName: [token.firstname, Validators.compose([Validators.required, Validators.maxLength(255)])], + firstName: [{value: token.firstname, disabled: (token.firstname && token.firstname.length > 0) ? true : false }, Validators.compose([Validators.required, Validators.maxLength(255)])], middleName: [null, [Validators.maxLength(255)]], - lastName: [token.lastname, Validators.compose([Validators.required, Validators.maxLength(255)])], + lastName: [{value: token.lastname , disabled: (token.lastname && token.lastname.length > 0) ? true : false }, Validators.compose([Validators.required, Validators.maxLength(255)])], birthDate: [null], alsoKnownAs: [null, Validators.compose([Validators.maxLength(255)])], businessName: [null, [Validators.maxLength(255)]] From 37f673a26c42201155fba187dae32fe864c43400 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Sun, 1 Mar 2020 23:36:37 -0800 Subject: [PATCH 009/589] KC integration changes --- src/app/app-routing.module.ts | 7 +- src/app/app.module.ts | 16 ++-- .../route-components/auth/auth.component.ts | 73 ------------------- .../choose-identity.component.html} | 0 .../choose-identity.component.scss} | 0 .../choose-identity.component.spec.ts | 25 +++++++ .../choose-identity.component.ts | 68 +++++++++++++++++ .../route-components.module.ts | 4 +- .../signin/signin.component.html | 2 + .../signin/signin.component.scss | 0 .../signin.component.spec.ts} | 12 +-- .../signin/signin.component.ts | 23 ++++++ src/app/services/data.json | 2 +- src/app/services/keycloak.service.ts | 15 ++-- 14 files changed, 150 insertions(+), 97 deletions(-) delete mode 100644 src/app/route-components/auth/auth.component.ts rename src/app/route-components/{auth/auth.component.html => choose-identity/choose-identity.component.html} (100%) rename src/app/route-components/{auth/auth.component.scss => choose-identity/choose-identity.component.scss} (100%) create mode 100644 src/app/route-components/choose-identity/choose-identity.component.spec.ts create mode 100644 src/app/route-components/choose-identity/choose-identity.component.ts create mode 100644 src/app/route-components/signin/signin.component.html create mode 100644 src/app/route-components/signin/signin.component.scss rename src/app/route-components/{auth/auth.component.spec.ts => signin/signin.component.spec.ts} (57%) create mode 100644 src/app/route-components/signin/signin.component.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index b81b9bfb..984bff5e 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -3,7 +3,7 @@ import { Routes, RouterModule } from '@angular/router'; import { LandingComponent } from './route-components/landing/landing.component'; import { GettingStarted1Component } from './route-components/getting-started1/getting-started1.component'; import { GettingStarted2Component } from './route-components/getting-started2/getting-started2.component'; -import { AuthComponent } from './route-components/auth/auth.component'; +import { ChooseIdentityComponent } from './route-components/choose-identity/choose-identity.component'; import { GettingStarted3Component } from './route-components/getting-started3/getting-started3.component'; import { GeneralInfoComponent } from './route-components/general-info/general-info.component'; import { MinistryConfirmationComponent } from './route-components/ministry-confirmation/ministry-confirmation.component'; @@ -19,13 +19,16 @@ import { VerifyYourIdentityComponent } from './route-components/verify-your-iden import { RequestTopicComponent } from './route-components/request-topic/request-topic.component'; import { ReviewSubmitCompleteComponent } from './route-components/review-submit-complete/review-submit-complete.component'; import { AdoptiveParentsComponent } from './route-components/adoptive-parents/adoptive-parents.component'; +import { SigninComponent } from './route-components/signin/signin.component'; + const routes: Routes = [ { path: '', component: LandingComponent }, { path: 'getting-started1', component: GettingStarted1Component }, { path: 'getting-started2', component: GettingStarted2Component }, - { path: 'auth', component: AuthComponent }, + { path: 'choose-identity', component: ChooseIdentityComponent }, { path: 'getting-started3', component: GettingStarted3Component }, + { path: 'signin', component: SigninComponent }, // General { path: 'general/fee-info', component: GeneralInfoComponent }, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 4a2f853f..338eabe8 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -14,13 +14,15 @@ import { RouteComponentsModule } from './route-components/route-components.modul import { FooterComponent } from './footer/footer.component'; import { ReactiveFormsModule } from '@angular/forms'; import { KeycloakService, KeyCloakFactory } from './services/keycloak.service'; +import { SigninComponent } from './route-components/signin/signin.component'; @NgModule({ declarations: [ AppComponent, CoreHeaderComponent, ProgressBarComponent, - FooterComponent + FooterComponent, + SigninComponent ], imports: [ BrowserModule, @@ -34,12 +36,12 @@ import { KeycloakService, KeyCloakFactory } from './services/keycloak.service'; ], providers: [ TransomApiClientService, - { - provide: APP_INITIALIZER, - useFactory: KeyCloakFactory, - deps: [KeycloakService], - multi: true - } + // { + // provide: APP_INITIALIZER, + // // useFactory: KeyCloakFactory, + // // deps: [KeycloakService], + // multi: true + // } ], bootstrap: [AppComponent, FooterComponent] }) diff --git a/src/app/route-components/auth/auth.component.ts b/src/app/route-components/auth/auth.component.ts deleted file mode 100644 index 77896eca..00000000 --- a/src/app/route-components/auth/auth.component.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; -import { BaseComponent } from 'src/app/utils-components/base/base.component'; -import { FoiRequest } from 'src/app/models/FoiRequest'; -import { FormBuilder, Validators } from '@angular/forms'; -import { DataService } from 'src/app/services/data.service'; -import {startWith} from "rxjs/operators"; -import {KeycloakService} from '../../services/keycloak.service'; - -@Component({ - templateUrl: './auth.component.html', - styleUrls: ['./auth.component.scss'] -}) -export class AuthComponent implements OnInit { - @ViewChild(BaseComponent) base: BaseComponent; - foiForm = this.fb.group({ - answerYes: [null, [Validators.required]] - }); - foiRequest: FoiRequest; - answerYes: boolean = null; - answerReceived: boolean; - continuetext = 'Start your request' - targetKey: string; - constructor(private fb: FormBuilder, private dataService: DataService, private keycloakService: KeycloakService) {} - - - ngOnInit() { - console.log(sessionStorage.getItem('KC_TOKEN')); - this.keycloakService.getTokenSubs().subscribe((token) => { - if (token !== 'undefined' && !!token && token.length > 1 ) { - this.base.goFoiForward(); - } - }); - if (sessionStorage.getItem('KC_TOKEN') !== 'undefined') { - this.base.goFoiForward(); - } else { - this.base.getFoiRouteData().subscribe(data => { - if (data) { - // Load the current values & populate the FormGroup. - this.foiRequest = this.dataService.getCurrentState(this.targetKey); - const initialValues = this.foiRequest.requestData[this.targetKey]; - this.foiForm.patchValue(initialValues); - - this.foiForm.valueChanges.pipe(startWith(initialValues)).subscribe(newValue => { - this.answerReceived = this.answerYes !== null; - this.answerYes = newValue.answerYes === 'true'; - if (this.answerYes) { - this.continuetext = 'Login With BC Service Card'; - } else { - this.continuetext = 'Continue without Logging In'; - } - this.base.continueDisabled = !this.answerReceived; - }); - } - }); - } - } - doContinue() { - if (this.answerYes) { - this.keycloakService.login(); - } else { - this.base.goFoiForward(); - } - // - } - doGoBack() { - this.base.goFoiBack(); - } - - get showAlert(): Boolean { - return this.answerReceived && !this.answerYes; - } - -} diff --git a/src/app/route-components/auth/auth.component.html b/src/app/route-components/choose-identity/choose-identity.component.html similarity index 100% rename from src/app/route-components/auth/auth.component.html rename to src/app/route-components/choose-identity/choose-identity.component.html diff --git a/src/app/route-components/auth/auth.component.scss b/src/app/route-components/choose-identity/choose-identity.component.scss similarity index 100% rename from src/app/route-components/auth/auth.component.scss rename to src/app/route-components/choose-identity/choose-identity.component.scss diff --git a/src/app/route-components/choose-identity/choose-identity.component.spec.ts b/src/app/route-components/choose-identity/choose-identity.component.spec.ts new file mode 100644 index 00000000..399d2904 --- /dev/null +++ b/src/app/route-components/choose-identity/choose-identity.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ChooseIdentityComponent } from './choose-identity.component'; + +describe('ChooseIdentityComponent', () => { + let component: ChooseIdentityComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ChooseIdentityComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ChooseIdentityComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/route-components/choose-identity/choose-identity.component.ts b/src/app/route-components/choose-identity/choose-identity.component.ts new file mode 100644 index 00000000..95921459 --- /dev/null +++ b/src/app/route-components/choose-identity/choose-identity.component.ts @@ -0,0 +1,68 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { BaseComponent } from 'src/app/utils-components/base/base.component'; +import { FoiRequest } from 'src/app/models/FoiRequest'; +import { FormBuilder, Validators } from '@angular/forms'; +import { DataService } from 'src/app/services/data.service'; +import {startWith} from "rxjs/operators"; +// import {KeycloakService} from '../../services/keycloak.service'; +import { Router } from '@angular/router'; + +@Component({ + templateUrl: './choose-identity.component.html', + styleUrls: ['./choose-identity.component.scss'] +}) +export class ChooseIdentityComponent implements OnInit { + @ViewChild(BaseComponent) base: BaseComponent; + foiForm = this.fb.group({ + answerYes: [null, [Validators.required]] + }); + foiRequest: FoiRequest; + answerYes: boolean = null; + answerReceived: boolean; + continuetext = 'Start your request' + targetKey: string; + constructor(private fb: FormBuilder, private dataService: DataService, public router: Router) {} + + + ngOnInit() { + console.log(sessionStorage.getItem('KC_TOKEN')); + + this.base.getFoiRouteData().subscribe(data => { + if (data) { + // Load the current values & populate the FormGroup. + this.foiRequest = this.dataService.getCurrentState(this.targetKey); + const initialValues = this.foiRequest.requestData[this.targetKey]; + this.foiForm.patchValue(initialValues); + + this.foiForm.valueChanges.pipe(startWith(initialValues)).subscribe(newValue => { + this.answerReceived = this.answerYes !== null; + this.answerYes = newValue.answerYes === 'true'; + if (this.answerYes) { + this.continuetext = 'Login With BC Service Card'; + } else { + this.continuetext = 'Continue without Logging In'; + } + this.base.continueDisabled = !this.answerReceived; + }); + } + }); + } + doContinue() { + if (this.answerYes) { + // this.keycloakService.login(); + this.router.navigateByUrl('signin') + } else { + sessionStorage.setItem('KC_TOKEN', null) + this.base.goFoiForward(); + } + // + } + doGoBack() { + this.base.goFoiBack(); + } + + get showAlert(): Boolean { + return this.answerReceived && !this.answerYes; + } + +} diff --git a/src/app/route-components/route-components.module.ts b/src/app/route-components/route-components.module.ts index bba35a71..27636233 100644 --- a/src/app/route-components/route-components.module.ts +++ b/src/app/route-components/route-components.module.ts @@ -6,7 +6,7 @@ import { GettingStarted2Component } from './getting-started2/getting-started2.co import { ReviewSubmitCompleteComponent } from './review-submit-complete/review-submit-complete.component'; import { ReactiveFormsModule } from '@angular/forms'; import { StartRequestComponent } from './start-request/start-request.component'; -import { AuthComponent } from './auth/auth.component'; +import { ChooseIdentityComponent } from './choose-identity/choose-identity.component'; import { GettingStarted3Component } from './getting-started3/getting-started3.component'; import { GeneralInfoComponent } from './general-info/general-info.component'; import { GeneralSelectMinistryComponent } from './general-select-ministry/general-select-ministry.component'; @@ -39,7 +39,7 @@ library.add(faSpinner); GettingStarted2Component, ReviewSubmitCompleteComponent, StartRequestComponent, - AuthComponent, + ChooseIdentityComponent, GettingStarted3Component, GeneralInfoComponent, GeneralInfoComponent, diff --git a/src/app/route-components/signin/signin.component.html b/src/app/route-components/signin/signin.component.html new file mode 100644 index 00000000..f5222ee4 --- /dev/null +++ b/src/app/route-components/signin/signin.component.html @@ -0,0 +1,2 @@ +

+

diff --git a/src/app/route-components/signin/signin.component.scss b/src/app/route-components/signin/signin.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/src/app/route-components/auth/auth.component.spec.ts b/src/app/route-components/signin/signin.component.spec.ts similarity index 57% rename from src/app/route-components/auth/auth.component.spec.ts rename to src/app/route-components/signin/signin.component.spec.ts index 884576c8..c64b0b29 100644 --- a/src/app/route-components/auth/auth.component.spec.ts +++ b/src/app/route-components/signin/signin.component.spec.ts @@ -1,20 +1,20 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { AuthComponent } from './auth.component'; +import { SigninComponent } from './signin.component'; -describe('AuthComponent', () => { - let component: AuthComponent; - let fixture: ComponentFixture; +describe('SigninComponent', () => { + let component: SigninComponent; + let fixture: ComponentFixture; beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ AuthComponent ] + declarations: [ SigninComponent ] }) .compileComponents(); })); beforeEach(() => { - fixture = TestBed.createComponent(AuthComponent); + fixture = TestBed.createComponent(SigninComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src/app/route-components/signin/signin.component.ts b/src/app/route-components/signin/signin.component.ts new file mode 100644 index 00000000..a9e2a858 --- /dev/null +++ b/src/app/route-components/signin/signin.component.ts @@ -0,0 +1,23 @@ +import { Component, OnInit } from '@angular/core'; +import { DataService } from 'src/app/services/data.service'; +import {KeycloakService} from '../../services/keycloak.service'; +import {Router} from '@angular/router' + +@Component({ + selector: 'app-signin', + templateUrl: './signin.component.html', + styleUrls: ['./signin.component.scss'] +}) +export class SigninComponent implements OnInit { + + constructor(private dataService: DataService, private keycloakService: KeycloakService, private router: Router) {} + + ngOnInit() { + this.keycloakService.init().then(() => { + console.log(this.keycloakService.getDecodedToken()); + + this.router.navigateByUrl('personal/select-about') + }); + } + +} diff --git a/src/app/services/data.json b/src/app/services/data.json index 45a198f4..912ca3dd 100644 --- a/src/app/services/data.json +++ b/src/app/services/data.json @@ -132,7 +132,7 @@ }, "personal": { "routes": [ - { "route": "auth", "progress": 1 }, + { "route": "choose-identity", "progress": 1 }, { "route": "personal/select-about", "progress": 2, diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index 5b1a8f5d..91298439 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -2,7 +2,8 @@ import { Injectable } from '@angular/core'; import * as jwt_decode from 'jwt-decode'; import { default as config } from "./keycloak-config.json"; import {BehaviorSubject, Observable} from 'rxjs'; -// import KeyCloak from 'keycloak-js' +import KeyCloak from 'keycloak-js' +import { KeycloakLoginOptions } from 'keycloak-js' declare var Keycloak: any; @@ -27,7 +28,13 @@ export class KeycloakService { init(): Promise { return new Promise((resolve, reject) => { this.keycloakAuth = new Keycloak(config); - this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'check-sso'}) + const kcLogin = this.keycloakAuth.login; + this.keycloakAuth.login = (options?: KeycloakLoginOptions) => { + options.idpHint = 'bcsc' + return kcLogin(options) + } + + this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'login-required'}) .success(() => { sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); if (this.keycloakAuth.token) { @@ -49,10 +56,6 @@ export class KeycloakService { return this.keycloakAuth.user; } - login(): void { - this.keycloakAuth.login({idpHint: 'bcsc'}) - } - getTokenSubs(): Observable { return this.tokenInfo.asObservable(); } From a7809460db50bf543d1a0c077e483f2df333d9f2 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Sun, 1 Mar 2020 23:46:47 -0800 Subject: [PATCH 010/589] KC integration changes --- .../choose-identity/choose-identity.component.ts | 4 +++- .../getting-started3/getting-started3.component.html | 2 +- src/app/services/keycloak.service.ts | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/app/route-components/choose-identity/choose-identity.component.ts b/src/app/route-components/choose-identity/choose-identity.component.ts index 95921459..88f146f9 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.ts +++ b/src/app/route-components/choose-identity/choose-identity.component.ts @@ -50,9 +50,11 @@ export class ChooseIdentityComponent implements OnInit { doContinue() { if (this.answerYes) { // this.keycloakService.login(); + console.log(this.base) + debugger this.router.navigateByUrl('signin') } else { - sessionStorage.setItem('KC_TOKEN', null) + sessionStorage.removeItem('KC_TOKEN') this.base.goFoiForward(); } // diff --git a/src/app/route-components/getting-started3/getting-started3.component.html b/src/app/route-components/getting-started3/getting-started3.component.html index 4bd746c5..a1cf83b7 100644 --- a/src/app/route-components/getting-started3/getting-started3.component.html +++ b/src/app/route-components/getting-started3/getting-started3.component.html @@ -5,7 +5,7 @@ [startupComponent]="true" >
-

Welcome {{firstName}}, {{lastName}}

+

What type of information are you looking for?

diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index 91298439..a9500c00 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -72,8 +72,8 @@ export class KeycloakService { return sessionStorage.getItem('KC_TOKEN') ? jwt_decode(sessionStorage.getItem('KC_TOKEN')) : { - 'firstname': null, - 'lastname': null + 'firstname': '', + 'lastname': '' } } From a4c03f71bfbbd2f184fa9a5d277cd58494076bda Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Mon, 2 Mar 2020 20:28:01 -0800 Subject: [PATCH 011/589] Changes with new keycloak configuration --- .../choose-identity.component.ts | 5 --- .../contact-info-options.component.ts | 23 +++++++++--- .../getting-started3.component.ts | 6 ---- .../signin/signin.component.ts | 2 -- .../verify-your-identity.component.ts | 14 +++++--- src/app/services/keycloak-config.json | 6 ++-- src/app/services/keycloak.service.ts | 35 +++---------------- 7 files changed, 36 insertions(+), 55 deletions(-) diff --git a/src/app/route-components/choose-identity/choose-identity.component.ts b/src/app/route-components/choose-identity/choose-identity.component.ts index 88f146f9..8bad612c 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.ts +++ b/src/app/route-components/choose-identity/choose-identity.component.ts @@ -25,8 +25,6 @@ export class ChooseIdentityComponent implements OnInit { ngOnInit() { - console.log(sessionStorage.getItem('KC_TOKEN')); - this.base.getFoiRouteData().subscribe(data => { if (data) { // Load the current values & populate the FormGroup. @@ -49,9 +47,6 @@ export class ChooseIdentityComponent implements OnInit { } doContinue() { if (this.answerYes) { - // this.keycloakService.login(); - console.log(this.base) - debugger this.router.navigateByUrl('signin') } else { sessionStorage.removeItem('KC_TOKEN') diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.ts b/src/app/route-components/contact-info-options/contact-info-options.component.ts index bf506b22..0191c72e 100644 --- a/src/app/route-components/contact-info-options/contact-info-options.component.ts +++ b/src/app/route-components/contact-info-options/contact-info-options.component.ts @@ -3,6 +3,7 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { FormBuilder, Validators } from '@angular/forms'; import { DataService } from 'src/app/services/data.service'; +import { KeycloakService } from '../../services/keycloak.service'; @Component({ templateUrl: './contact-info-options.component.html', @@ -25,12 +26,26 @@ export class ContactInfoOptionsComponent implements OnInit { foiRequest: FoiRequest; targetKey: string = 'contactInfoOptions'; - constructor(private fb: FormBuilder, private dataService: DataService) {} + constructor(private fb: FormBuilder, private dataService: DataService, private keycloak: KeycloakService) {} ngOnInit() { + // Update email if the user is authenticated + const token = this.keycloak.getDecodedToken(); + const isAuthenticated: boolean = (token !== undefined && token.sub !== undefined); + this.foiForm = this.fb.group({ + email: [{value: token.email, disabled: isAuthenticated}], + phonePrimary: [null], + phoneSecondary: [null], + address: [null], + city: [null], + postal: [null], + province: [null], + country: [null] + }); + // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); - this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey], {emitEvent: true}); } /** @@ -39,7 +54,7 @@ export class ContactInfoOptionsComponent implements OnInit { allowContinue() { const formData = this.foiForm.value; let result = false; - if (formData.email) { + if (formData.email || this.keycloak.getDecodedToken().email) { result = true; } if (formData.phonePrimary) { @@ -72,7 +87,7 @@ export class ContactInfoOptionsComponent implements OnInit { // Personal non-Adoption can skip over the previous route, 'adoptive-parents'. this.base.goSkipBack(); return; - } + } this.base.goFoiBack(); } } diff --git a/src/app/route-components/getting-started3/getting-started3.component.ts b/src/app/route-components/getting-started3/getting-started3.component.ts index 1c706791..11ac8136 100644 --- a/src/app/route-components/getting-started3/getting-started3.component.ts +++ b/src/app/route-components/getting-started3/getting-started3.component.ts @@ -29,12 +29,6 @@ export class GettingStarted3Component implements OnInit { // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); - if(sessionStorage.getItem('KC_TOKEN') !== 'undefined') { - let token = this.keycloakService.getDecodedToken(); - this.firstName = token.firstname; - this.lastName = token.lastname; - this.authenticated = true; - } } doContinue() { diff --git a/src/app/route-components/signin/signin.component.ts b/src/app/route-components/signin/signin.component.ts index a9e2a858..72979f13 100644 --- a/src/app/route-components/signin/signin.component.ts +++ b/src/app/route-components/signin/signin.component.ts @@ -14,8 +14,6 @@ export class SigninComponent implements OnInit { ngOnInit() { this.keycloakService.init().then(() => { - console.log(this.keycloakService.getDecodedToken()); - this.router.navigateByUrl('personal/select-about') }); } diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts index 6c055d20..8d17105c 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts @@ -23,13 +23,17 @@ export class VerifyYourIdentityComponent implements OnInit { constructor(private fb: FormBuilder, private dataService: DataService, private keycloak: KeycloakService) {} ngOnInit() { - let token = this.keycloak.getDecodedToken(); - console.log('token') + const token = this.keycloak.getDecodedToken(); + const isAuthenticated: boolean = token !== undefined && token.sub !== undefined; + const birthDate = new Date(token.birthDate + 'T00:00:00'); this.foiForm = this.fb.group({ - firstName: [{value: token.firstname, disabled: (token.firstname && token.firstname.length > 0) ? true : false }, Validators.compose([Validators.required, Validators.maxLength(255)])], + firstName: [{value: token.firstName, disabled: isAuthenticated}, + Validators.compose([Validators.required, Validators.maxLength(255)])], middleName: [null, [Validators.maxLength(255)]], - lastName: [{value: token.lastname , disabled: (token.lastname && token.lastname.length > 0) ? true : false }, Validators.compose([Validators.required, Validators.maxLength(255)])], - birthDate: [null], + lastName: [{value: token.lastName , disabled: isAuthenticated }, + Validators.compose([Validators.required, Validators.maxLength(255)])], + birthDate: [{value: birthDate , disabled: isAuthenticated }, + Validators.compose([Validators.required, Validators.maxLength(12)])], alsoKnownAs: [null, Validators.compose([Validators.maxLength(255)])], businessName: [null, [Validators.maxLength(255)]] }); diff --git a/src/app/services/keycloak-config.json b/src/app/services/keycloak-config.json index 5e301177..2f12f80c 100644 --- a/src/app/services/keycloak-config.json +++ b/src/app/services/keycloak-config.json @@ -1,9 +1,9 @@ { - "realm": "fcf0kpqr", + "realm": "5k8dbl4h", "url": "https://sso-dev.pathfinder.gov.bc.ca/auth", - "clientId": "sbc-auth-web", + "clientId": "foi-web", "credentials": { - "secret": "aeb2b9bc-672b-4574-8bc8-e76e853c37cb", + "secret": "c31c5b5c-f958-4c1d-9454-2af58892eac5", "ssl-required": "external", "public-client": true } diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index a9500c00..fde3b254 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -19,11 +19,6 @@ export function KeyCloakFactory(keycloakService: KeycloakService) { export class KeycloakService { private keycloakAuth: any; - private tokenInfo: BehaviorSubject; - - constructor() { - this.tokenInfo= new BehaviorSubject(''); - } init(): Promise { return new Promise((resolve, reject) => { @@ -37,10 +32,6 @@ export class KeycloakService { this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'login-required'}) .success(() => { sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); - if (this.keycloakAuth.token) { - this.tokenInfo.next(this.keycloakAuth.token); - this.initUser(); - } resolve(); }) .error(() => { @@ -49,32 +40,16 @@ export class KeycloakService { }); } - getToken(): string { - return this.keycloakAuth.token; - } - getUserName(): string { - return this.keycloakAuth.user; - } - - getTokenSubs(): Observable { - return this.tokenInfo.asObservable(); - } - - initUser(): void { - if (sessionStorage.getItem('KC_TOKEN')) { - const decoded = jwt_decode(sessionStorage.getItem('KC_TOKEN')); - console.log('this.parsedToken ,' + JSON.stringify(decoded)); - } - } getDecodedToken(): any { - console.log(sessionStorage.getItem('KC_TOKEN')) return sessionStorage.getItem('KC_TOKEN') ? jwt_decode(sessionStorage.getItem('KC_TOKEN')) : { - 'firstname': '', - 'lastname': '' - } + firstName: '', + lastName: '', + email: '', + birthDate: '' + }; } } From 9ac7c5597f55b47ae94bab5b47353b896609e7b6 Mon Sep 17 00:00:00 2001 From: saravankumarpa Date: Mon, 2 Mar 2020 22:43:16 -0800 Subject: [PATCH 012/589] configs end point added --- api/index.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/api/index.js b/api/index.js index 5f3a37f1..c060e4d1 100644 --- a/api/index.js +++ b/api/index.js @@ -75,11 +75,28 @@ transom.configure(transomSmtp, { transom .initialize(apiDefinition) .then(function(server) { + console.log('--------***s') server.get('/', function(req, res, next) { res.send('FOI Request API Server'); next(); }); + server.get('/api/v1/configs', function (req, res, next) { + const kcConfigs = { + realm:process.env.FOI_KC_REALM, + url:process.env.FOI_KC_URL, + clientId:process.env.FOI_KC_CLIENTID, + credentials:process.env.FOI_KC_CREDENTIALS, + secret:process.env.FOI_KC_SECRET, + sslrequired:process.env.FOI_KC_SSL_REQUIRED, + "public-client":process.env.FOI_KC_PUBLIC_CLIENT + + } + console.log('kcConfigs'+JSON.stringify(kcConfigs)) + res.json(kcConfigs); + next(); + }); + server.use(function(req,res,next){ req.log.info("(" + req.method + ")" + req.url); next(); From 5daac86fb2c134545cba27837d1f3db7cf476c4d Mon Sep 17 00:00:00 2001 From: saravankumarpa Date: Mon, 2 Mar 2020 23:23:17 -0800 Subject: [PATCH 013/589] Fixed the direct url --- angular.json | 10 +++++++--- src/app/app.module.ts | 1 - src/app/services/keycloak.service.ts | 17 ++++++----------- src/index.html | 1 - 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/angular.json b/angular.json index 7c60ed42..17839e61 100644 --- a/angular.json +++ b/angular.json @@ -31,7 +31,9 @@ "styles": [ "src/styles.scss" ], - "scripts": [], + "scripts": [ + "./node_modules/keycloak-js/dist/keycloak.js" + ], "es5BrowserSupport": true }, "configurations": { @@ -89,7 +91,9 @@ "styles": [ "src/styles.scss" ], - "scripts": [], + "scripts": [ + "./node_modules/keycloak-js/dist/keycloak.js" + ], "assets": [ "src/favicon.ico", "src/assets" @@ -140,4 +144,4 @@ } }, "defaultProject": "bcfoi" -} \ No newline at end of file +} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 338eabe8..530204a0 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -13,7 +13,6 @@ import { ServicesModule } from './services/services.module'; import { RouteComponentsModule } from './route-components/route-components.module'; import { FooterComponent } from './footer/footer.component'; import { ReactiveFormsModule } from '@angular/forms'; -import { KeycloakService, KeyCloakFactory } from './services/keycloak.service'; import { SigninComponent } from './route-components/signin/signin.component'; @NgModule({ diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index fde3b254..ca60f611 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -1,17 +1,12 @@ import { Injectable } from '@angular/core'; import * as jwt_decode from 'jwt-decode'; -import { default as config } from "./keycloak-config.json"; +import { default as config } from './keycloak-config.json'; import {BehaviorSubject, Observable} from 'rxjs'; -import KeyCloak from 'keycloak-js' -import { KeycloakLoginOptions } from 'keycloak-js' +import KeyCloak from 'keycloak-js'; +import { KeycloakLoginOptions } from 'keycloak-js'; declare var Keycloak: any; -export function KeyCloakFactory(keycloakService: KeycloakService) { - return () => { - keycloakService.init(); - }; -} @Injectable({ providedIn: 'root' @@ -25,9 +20,9 @@ export class KeycloakService { this.keycloakAuth = new Keycloak(config); const kcLogin = this.keycloakAuth.login; this.keycloakAuth.login = (options?: KeycloakLoginOptions) => { - options.idpHint = 'bcsc' - return kcLogin(options) - } + options.idpHint = 'bcsc'; + return kcLogin(options); + }; this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'login-required'}) .success(() => { diff --git a/src/index.html b/src/index.html index d0de4532..95a3f579 100644 --- a/src/index.html +++ b/src/index.html @@ -1,7 +1,6 @@ - FOI Request | B.C. Government From 0b260d5068e58656e57d4a89a9d7fa83bca2ebba Mon Sep 17 00:00:00 2001 From: saravankumarpa Date: Tue, 3 Mar 2020 15:53:45 -0800 Subject: [PATCH 014/589] corrected vars --- api/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/index.js b/api/index.js index c060e4d1..2048db0b 100644 --- a/api/index.js +++ b/api/index.js @@ -88,8 +88,8 @@ transom clientId:process.env.FOI_KC_CLIENTID, credentials:process.env.FOI_KC_CREDENTIALS, secret:process.env.FOI_KC_SECRET, - sslrequired:process.env.FOI_KC_SSL_REQUIRED, - "public-client":process.env.FOI_KC_PUBLIC_CLIENT + sslRequired:process.env.FOI_KC_SSL_REQUIRED, + publiCclient:process.env.FOI_KC_PUBLIC_CLIENT } console.log('kcConfigs'+JSON.stringify(kcConfigs)) From 3a88ffed2acfd1da9edc910b13772398fd0e6235 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Wed, 4 Mar 2020 22:05:04 -0800 Subject: [PATCH 015/589] Added snowplow analytics code --- src/index.html | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/index.html b/src/index.html index 95a3f579..3571223a 100644 --- a/src/index.html +++ b/src/index.html @@ -7,6 +7,29 @@ + // + + // +
From 1e80bc32c6a16a47b4237205a271fc8ce2897a74 Mon Sep 17 00:00:00 2001 From: Saravan PA Date: Thu, 5 Mar 2020 09:29:30 -0800 Subject: [PATCH 016/589] Update index.html --- src/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.html b/src/index.html index 3571223a..30766b08 100644 --- a/src/index.html +++ b/src/index.html @@ -7,7 +7,7 @@ - // + - // + From 9ef2b1928aab80eadf694f1dc9e1a5306af7e7b4 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Fri, 6 Mar 2020 06:46:30 -0800 Subject: [PATCH 018/589] Added jwt verifier code --- api/apiAuth.js | 49 ++++++ api/apiCaptcha.js | 7 +- api/apiDefinition.js | 5 +- api/authCfg.js | 8 + api/package-lock.json | 364 ++++++++++++++++++++++++++++++++++++++++++ api/package.json | 1 + 6 files changed, 432 insertions(+), 2 deletions(-) create mode 100644 api/apiAuth.js create mode 100644 api/authCfg.js diff --git a/api/apiAuth.js b/api/apiAuth.js new file mode 100644 index 00000000..63663e64 --- /dev/null +++ b/api/apiAuth.js @@ -0,0 +1,49 @@ +'use strict'; + + +var jwt = require('jsonwebtoken'); +var jwksClient = require('jwks-rsa'); + + + +function authInit(options) { + + var client = jwksClient({ + jwksUri: 'https://sso-dev.pathfinder.gov.bc.ca/auth/realms/5k8dbl4h/protocol/openid-connect/certs' + }) + + const JWT_TOKEN_HEADER = options.CAPTCHA_TOKEN_HEADER || 'Authorization'; // the request header where we expect the jwt token + + function getKey(header, callback){ + client.getSigningKey(header.kid, function(err, key) { + var signingKey = key.publicKey || key.rsaPublicKey; + callback(null, signingKey); + }); + } + + return { + + verifyJWTResponseMiddleware: function(req, res, next) { + var token = req.headers[JWT_TOKEN_HEADER.toLowerCase()] || ''; + token = token.replace('Bearer ', ''); + + jwt.verify(token, getKey, options, function(err, decoded) { + if (err){ + console.log('invalid token:::::::::::::::::::----------------------------') + //res.send(401, 'Invalid JWT'); + next(); + req.verified = false + } else { + console.log('VALID token:::::::::::::::::::----------------------------') + req.verified = true + next(); + } + }); + + } + + } + +} + +module.exports = authInit; diff --git a/api/apiCaptcha.js b/api/apiCaptcha.js index 4c6d78be..f1d6c2f0 100644 --- a/api/apiCaptcha.js +++ b/api/apiCaptcha.js @@ -221,9 +221,14 @@ function captchaInit(options) { getAudio(req.body, req).then(function(ret) { res.send(ret); next(); - }); + }); }, verifyJWTResponseMiddleware: function(req, res, next) { + if(req.verified) { + console.log('Request is already validated') + next(); + } + console.log('req.verified ',req.verified ) var token = req.headers[CAPTCHA_TOKEN_HEADER.toLowerCase()] || ''; token = token.replace('Bearer ', ''); var nonce = req.headers[CAPTCHA_NONCE_HEADER]; diff --git a/api/apiDefinition.js b/api/apiDefinition.js index 7210a5be..53d6747a 100644 --- a/api/apiDefinition.js +++ b/api/apiDefinition.js @@ -1,7 +1,10 @@ const customFunctions = require('./apiCustomFunctions'); const apiCaptchaFx = require('./apiCaptcha'); +const apiAuthFx = require('./apiAuth'); const captchaCfg = require('./captchaCfg'); +const authCfg = require('./authCfg'); const apiCaptcha = apiCaptchaFx(captchaCfg); +const apiAuth = apiAuthFx(authCfg); const RotatingFileStream = require('bunyan-rotating-file-stream'); module.exports = { @@ -48,7 +51,7 @@ module.exports = { functions: { submitFoiRequest: { methods: ['POST'], - preMiddleware: [apiCaptcha.verifyJWTResponseMiddleware], + preMiddleware: [apiAuth.verifyJWTResponseMiddleware, apiCaptcha.verifyJWTResponseMiddleware], function: customFunctions.submitFoiRequest } } diff --git a/api/authCfg.js b/api/authCfg.js new file mode 100644 index 00000000..af07b70d --- /dev/null +++ b/api/authCfg.js @@ -0,0 +1,8 @@ +'use strict'; + +module.exports = { + CAPTCHA_TOKEN_SECRET : process.env.CAPTCHA_TOKEN_SECRET || 'defaultSecret', + CAPTCHA_EXPIRY_MINUTES: '15', + CAPTCHA_TOKEN_HEADER: 'Authorization', + CAPTCHA_NONCE_HEADER: 'captcha-nonce' +}; \ No newline at end of file diff --git a/api/package-lock.json b/api/package-lock.json index e02c5b93..65bec728 100644 --- a/api/package-lock.json +++ b/api/package-lock.json @@ -232,17 +232,105 @@ "nodemailer": "^4.3.1" } }, + "@types/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", + "requires": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "@types/connect": { + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", + "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==", + "requires": { + "@types/node": "*" + } + }, + "@types/express": { + "version": "4.17.3", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz", + "integrity": "sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg==", + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "*", + "@types/serve-static": "*" + } + }, + "@types/express-jwt": { + "version": "0.0.42", + "resolved": "https://registry.npmjs.org/@types/express-jwt/-/express-jwt-0.0.42.tgz", + "integrity": "sha512-WszgUddvM1t5dPpJ3LhWNH8kfNN8GPIBrAGxgIYXVCEGx6Bx4A036aAuf/r5WH9DIEdlmp7gHOYvSM6U87B0ag==", + "requires": { + "@types/express": "*", + "@types/express-unless": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.2.tgz", + "integrity": "sha512-El9yMpctM6tORDAiBwZVLMcxoTMcqqRO9dVyYcn7ycLWbvR8klrDn8CAOwRfZujZtWD7yS/mshTdz43jMOejbg==", + "requires": { + "@types/node": "*", + "@types/range-parser": "*" + } + }, + "@types/express-unless": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@types/express-unless/-/express-unless-0.5.1.tgz", + "integrity": "sha512-5fuvg7C69lemNgl0+v+CUxDYWVPSfXHhJPst4yTLcqi4zKJpORCxnDrnnilk3k0DTq/WrAUdvXFs01+vUqUZHw==", + "requires": { + "@types/express": "*" + } + }, "@types/lodash": { "version": "4.14.120", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.120.tgz", "integrity": "sha512-jQ21kQ120mo+IrDs1nFNVm/AsdFxIx2+vZ347DbogHJPd/JzKNMOqU6HCYin1W6v8l5R9XSO2/e9cxmn7HAnVw==" }, + "@types/mime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", + "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==" + }, + "@types/node": { + "version": "13.7.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz", + "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==" + }, + "@types/range-parser": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", + "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" + }, + "@types/serve-static": { + "version": "1.13.3", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", + "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", + "requires": { + "@types/express-serve-static-core": "*", + "@types/mime": "*" + } + }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, + "ajv": { + "version": "6.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz", + "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-align": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", @@ -378,12 +466,27 @@ "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", "dev": true }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", + "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" + }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -672,6 +775,11 @@ "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==" }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, "chai": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", @@ -873,6 +981,14 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", @@ -1121,6 +1237,11 @@ "rimraf": "^2.2.8" } }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, "detect-node": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", @@ -1307,6 +1428,11 @@ } } }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "extend-shallow": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", @@ -1413,6 +1539,16 @@ "resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.0.tgz", "integrity": "sha512-WQSYVKn6tDW/3htASeUkrx5LcnuTENQIZQPCVlwdnvIJ7bYtSpoJYq38MgUJnx1CQIR1gjZ8HJxAEcN4gqugBg==" }, + "fast-deep-equal": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", + "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", @@ -1473,6 +1609,21 @@ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", "dev": true }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "formidable": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", @@ -2182,6 +2333,20 @@ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=" }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -2619,6 +2784,11 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -2635,6 +2805,11 @@ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, "issue-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/issue-regex/-/issue-regex-2.0.0.tgz", @@ -2693,6 +2868,16 @@ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, "jsonwebtoken": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz", @@ -2737,6 +2922,63 @@ "safe-buffer": "^5.0.1" } }, + "jwks-rsa": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-1.7.0.tgz", + "integrity": "sha512-tq7DVJt9J6wTvl9+AQfwZIiPSuY2Vf0F+MovfRTFuBqLB1xgDVhegD33ChEAQ6yBv9zFvUIyj4aiwrSA5VehUw==", + "requires": { + "@types/express-jwt": "0.0.42", + "debug": "^4.1.0", + "jsonwebtoken": "^8.5.1", + "limiter": "^1.1.4", + "lru-memoizer": "^2.0.1", + "ms": "^2.1.2", + "request": "^2.88.0" + }, + "dependencies": { + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "jws": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.1.tgz", @@ -2815,6 +3057,11 @@ "package-json": "^4.0.0" } }, + "limiter": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/limiter/-/limiter-1.1.5.tgz", + "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" + }, "listr": { "version": "0.14.3", "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", @@ -2989,6 +3236,11 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "lodash.debounce": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", @@ -3087,6 +3339,26 @@ "yallist": "^2.1.2" } }, + "lru-memoizer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/lru-memoizer/-/lru-memoizer-2.1.0.tgz", + "integrity": "sha512-oKjxgJhL+m1wfEkez7/a6iyRZUdohej+2u04qCaAQ7BBfx/qD4RH3jOQhPsd8Y3pcm7IhcNtE3kCEIDCMPiJFQ==", + "requires": { + "lodash.clonedeep": "^4.5.0", + "lru-cache": "~4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", + "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", + "requires": { + "pseudomap": "^1.0.1", + "yallist": "^2.0.0" + } + } + } + }, "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -3157,6 +3429,19 @@ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, + "mime-db": { + "version": "1.43.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", + "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + }, + "mime-types": { + "version": "2.1.26", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", + "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "requires": { + "mime-db": "1.43.0" + } + }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", @@ -4583,6 +4868,11 @@ } } }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -4819,6 +5109,11 @@ "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", "dev": true }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, "pidusage": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-1.2.0.tgz", @@ -4873,6 +5168,11 @@ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" }, + "psl": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", + "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" + }, "pstree.remy": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.6.tgz", @@ -4888,6 +5188,11 @@ "once": "^1.3.1" } }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, "qs": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.6.0.tgz", @@ -5014,6 +5319,40 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + } + } + }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -5808,6 +6147,15 @@ "nopt": "~1.0.10" } }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, "trim-newlines": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", @@ -5824,6 +6172,14 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", @@ -5995,6 +6351,14 @@ "xdg-basedir": "^3.0.0" } }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", diff --git a/api/package.json b/api/package.json index 6811d3d3..17293d53 100644 --- a/api/package.json +++ b/api/package.json @@ -24,6 +24,7 @@ "bunyan-rotating-file-stream": "^1.6.3", "dotenv": "^6.2.0", "jsonwebtoken": "^8.5.0", + "jwks-rsa": "^1.7.0", "lame": "^1.2.4", "streamifier": "^0.1.1", "svg-captcha": "^1.3.12", From 215bc4a758f2583b4ee2b45e9d995cb086dd498f Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 7 Mar 2020 12:44:26 -0800 Subject: [PATCH 019/589] Email new format added --- api/apiAuth.js | 9 +++++++-- api/apiCaptcha.js | 4 ++-- api/apiCustomFunctions.js | 2 +- api/emailLayout.js | 25 ++++++++++++++++++++++++- 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/api/apiAuth.js b/api/apiAuth.js index 63663e64..5777a769 100644 --- a/api/apiAuth.js +++ b/api/apiAuth.js @@ -32,10 +32,15 @@ function authInit(options) { console.log('invalid token:::::::::::::::::::----------------------------') //res.send(401, 'Invalid JWT'); next(); - req.verified = false + req.isAuthorised = false } else { console.log('VALID token:::::::::::::::::::----------------------------') - req.verified = true + req.isAuthorised = true + req.userDetails = {"firstName":decoded.firstName, + "lastName":decoded.lastName, + "email":decoded.email, + "birthDate":decoded.birthDate + } next(); } }); diff --git a/api/apiCaptcha.js b/api/apiCaptcha.js index f1d6c2f0..2b114b42 100644 --- a/api/apiCaptcha.js +++ b/api/apiCaptcha.js @@ -224,8 +224,8 @@ function captchaInit(options) { }); }, verifyJWTResponseMiddleware: function(req, res, next) { - if(req.verified) { - console.log('Request is already validated') + if(req.isAuthorised && req.userDetails) { + console.log('Request is already validated'+req.userDetails.firstName); next(); } console.log('req.verified ',req.verified ) diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index 10403ee4..4cff69e4 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -20,7 +20,7 @@ function submitFoiRequest(server, req, res, next) { }; req.log.info(`Sending message to ${foiRequestInbox}`, data); - const foiHtml = emailLayout.renderEmail(data.params); + const foiHtml = emailLayout.renderEmail(data.params,req.isAuthorised,req.userDetails); const foiAttachments = []; if (req.files) { Object.keys(req.files).map(f => { diff --git a/api/emailLayout.js b/api/emailLayout.js index 5a638b8b..d408a1ab 100644 --- a/api/emailLayout.js +++ b/api/emailLayout.js @@ -46,6 +46,14 @@ module.exports = function EmailLayout() { .trim(); }; + this.getAuthorisedDetailsTable = function (data) { + let result ='' + result += this.tableRow('First Name of the Submitter', data.firstName); + result += this.tableRow('Last Name of the Submitter', data.lastName); + result += this.tableRow('Email of the Submitter', data.email); + result += this.tableRow('Date Of Birth of the Submitter', data.birthDate); + return result + } this.general = function(data) { let result = this.tableHeader('Request Description'); // Removed Topic from the generated email body. @@ -217,8 +225,23 @@ module.exports = function EmailLayout() { return result; }; - this.renderEmail = function(data) { + this.renderEmail = function(data ,isAuthorised , authorisedDetails) { let content = this.tableHeader('Request Records'); + this.table() + if (isAuthorised) { + content += this.tableRow( + 'Request Authorisation','BC Service Card' + ); + + content += this.tableRow( + 'Authorised Details',this.table(this.authorisedDetails(authorisedDetails)) + ); + + } else { + content += this.tableRow( + 'This request is not authorised.' + ); + } content += this.tableRow( 'Request Type', data.requestData.requestType.requestType From d1b373162fd509d2aa8653023350d252cd6ea4fd Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 7 Mar 2020 14:52:22 -0800 Subject: [PATCH 020/589] either captcha or token validation --- api/apiAuth.js | 11 +++++++---- api/apiCaptcha.js | 3 ++- api/emailLayout.js | 4 ---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/api/apiAuth.js b/api/apiAuth.js index 5777a769..e6592489 100644 --- a/api/apiAuth.js +++ b/api/apiAuth.js @@ -13,6 +13,7 @@ function authInit(options) { }) const JWT_TOKEN_HEADER = options.CAPTCHA_TOKEN_HEADER || 'Authorization'; // the request header where we expect the jwt token + const CAPTCHA_NONCE_HEADER = options.CAPTCHA_NONCE_HEADER || 'captcha-nonce'; // the request header where we expect the client nonce function getKey(header, callback){ client.getSigningKey(header.kid, function(err, key) { @@ -24,17 +25,19 @@ function authInit(options) { return { verifyJWTResponseMiddleware: function(req, res, next) { + if (req.headers[CAPTCHA_NONCE_HEADER]) { + req.isAuthorised = false + return next(); + } var token = req.headers[JWT_TOKEN_HEADER.toLowerCase()] || ''; token = token.replace('Bearer ', ''); jwt.verify(token, getKey, options, function(err, decoded) { if (err){ - console.log('invalid token:::::::::::::::::::----------------------------') - //res.send(401, 'Invalid JWT'); - next(); req.isAuthorised = false + return next(); + } else { - console.log('VALID token:::::::::::::::::::----------------------------') req.isAuthorised = true req.userDetails = {"firstName":decoded.firstName, "lastName":decoded.lastName, diff --git a/api/apiCaptcha.js b/api/apiCaptcha.js index 2b114b42..2dc1d498 100644 --- a/api/apiCaptcha.js +++ b/api/apiCaptcha.js @@ -224,7 +224,8 @@ function captchaInit(options) { }); }, verifyJWTResponseMiddleware: function(req, res, next) { - if(req.isAuthorised && req.userDetails) { + // if there is a captcha header , it shud be validated by captcha verifier + if(req.isAuthorised && req.userDetails && !req.headers[CAPTCHA_NONCE_HEADER]) { console.log('Request is already validated'+req.userDetails.firstName); next(); } diff --git a/api/emailLayout.js b/api/emailLayout.js index d408a1ab..1a1d8091 100644 --- a/api/emailLayout.js +++ b/api/emailLayout.js @@ -237,10 +237,6 @@ module.exports = function EmailLayout() { 'Authorised Details',this.table(this.authorisedDetails(authorisedDetails)) ); - } else { - content += this.tableRow( - 'This request is not authorised.' - ); } content += this.tableRow( 'Request Type', From 4174081ca5515808563da77919f5d1140e23dd6f Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 7 Mar 2020 16:27:01 -0800 Subject: [PATCH 021/589] hide captcha for logged in user --- api/apiCaptcha.js | 2 +- api/emailLayout.js | 2 +- .../review-submit.component.html | 4 +- .../review-submit/review-submit.component.ts | 33 +++++---- src/app/services/data.service.ts | 68 +++++++++---------- src/app/services/keycloak.service.ts | 3 + 6 files changed, 62 insertions(+), 50 deletions(-) diff --git a/api/apiCaptcha.js b/api/apiCaptcha.js index 2dc1d498..871ad24e 100644 --- a/api/apiCaptcha.js +++ b/api/apiCaptcha.js @@ -227,7 +227,7 @@ function captchaInit(options) { // if there is a captcha header , it shud be validated by captcha verifier if(req.isAuthorised && req.userDetails && !req.headers[CAPTCHA_NONCE_HEADER]) { console.log('Request is already validated'+req.userDetails.firstName); - next(); + return next(); } console.log('req.verified ',req.verified ) var token = req.headers[CAPTCHA_TOKEN_HEADER.toLowerCase()] || ''; diff --git a/api/emailLayout.js b/api/emailLayout.js index 1a1d8091..a39d197e 100644 --- a/api/emailLayout.js +++ b/api/emailLayout.js @@ -234,7 +234,7 @@ module.exports = function EmailLayout() { ); content += this.tableRow( - 'Authorised Details',this.table(this.authorisedDetails(authorisedDetails)) + 'Authorised Details',this.table(this.getAuthorisedDetailsTable(authorisedDetails)) ); } diff --git a/src/app/route-components/review-submit/review-submit.component.html b/src/app/route-components/review-submit/review-submit.component.html index c7ae120d..df30b768 100644 --- a/src/app/route-components/review-submit/review-submit.component.html +++ b/src/app/route-components/review-submit/review-submit.component.html @@ -139,7 +139,7 @@

Review your request

-
+
Review your request
--> - +
diff --git a/src/app/route-components/review-submit/review-submit.component.ts b/src/app/route-components/review-submit/review-submit.component.ts index bc2e69ea..96650214 100644 --- a/src/app/route-components/review-submit/review-submit.component.ts +++ b/src/app/route-components/review-submit/review-submit.component.ts @@ -4,6 +4,7 @@ import { DataService } from 'src/app/services/data.service'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { CaptchaComponent } from 'src/app/utils-components/captcha/captcha.component'; import { DomSanitizer } from '@angular/platform-browser'; +import { KeycloakService } from '../../services/keycloak.service'; @Component({ templateUrl: './review-submit.component.html', @@ -11,16 +12,16 @@ import { DomSanitizer } from '@angular/platform-browser'; }) export class ReviewSubmitComponent implements OnInit { @ViewChild(BaseComponent) base: BaseComponent; - @ViewChild('captchaComponent') captchaComponent: CaptchaComponent + @ViewChild('captchaComponent') captchaComponent: CaptchaComponent; foiRequest: FoiRequest; foiRequestPretty: string; - captchaApiBaseUrl: string = '/api'; - captchaComplete: boolean = false; - isBusy: boolean = false; // during submit! - authToken: string = ''; - captchaNonce: string = '69879887sdsas$#'; - constructor(private dataService: DataService, private sanitizer: DomSanitizer) {} + captchaApiBaseUrl = '/api'; + captchaComplete = false; + isBusy = false; // during submit! + authToken = ''; + captchaNonce = '69879887sdsas$#'; + constructor(private dataService: DataService, private sanitizer: DomSanitizer, private keycloakService: KeycloakService) {} ngOnInit() { this.foiRequest = this.dataService.getCurrentState(); @@ -29,6 +30,14 @@ export class ReviewSubmitComponent implements OnInit { } // foiRequestPretty is used for debugging only this.foiRequestPretty = JSON.stringify(this.foiRequest, null, 2); + + // see if keycloak token is there.set it to authToken + if (this.keycloakService.getDecodedToken() && this.keycloakService.getDecodedToken().email) { + this.authToken = this.keycloakService.getToken(); + this.captchaComplete = true; + this.captchaNonce = '' + } + } getBase64Data(storageKey) { @@ -37,12 +46,12 @@ export class ReviewSubmitComponent implements OnInit { return imagePath; } - onValidToken(tokenEvent){ - this.authToken = tokenEvent.replace('\n','') ; + onValidToken(tokenEvent) { + this.authToken = tokenEvent.replace('\n', '') ; this.captchaComplete = true; } - submitDisabled () { + submitDisabled() { return this.isBusy || !this.captchaComplete; } @@ -53,8 +62,8 @@ export class ReviewSubmitComponent implements OnInit { this.base.goFoiForward(); }, error => { this.isBusy = false; - console.log("Submission failed: ", error); - alert("Temporarily unable to submit your request. Please try again in a few minutes."); + console.log('Submission failed: ', error); + alert('Temporarily unable to submit your request. Please try again in a few minutes.'); this.captchaComponent.forceRefresh(); this.captchaComplete = false; }); diff --git a/src/app/services/data.service.ts b/src/app/services/data.service.ts index d5deaf97..97c968e3 100644 --- a/src/app/services/data.service.ts +++ b/src/app/services/data.service.ts @@ -1,18 +1,18 @@ -import { Injectable } from "@angular/core"; -import { default as data } from "./data.json"; -import { Observable, of } from "rxjs"; -import { FoiRoute } from "../models/FoiRoute"; -import { FoiRequest, BlobFile } from "../models/FoiRequest"; -import { TransomApiClientService } from "../transom-api-client.service"; -import { FormGroup } from "@angular/forms"; +import { Injectable } from '@angular/core'; +import { default as data } from './data.json'; +import { Observable, of } from 'rxjs'; +import { FoiRoute } from '../models/FoiRoute'; +import { FoiRequest, BlobFile } from '../models/FoiRequest'; +import { TransomApiClientService } from '../transom-api-client.service'; +import { FormGroup } from '@angular/forms'; @Injectable({ - providedIn: "root" + providedIn: 'root' }) export class DataService { foiRoutes: FoiRoute[]; - childFileKey: string = "childFileAttachment"; - personFileKey: string = "personFileAttachment"; + childFileKey = 'childFileAttachment'; + personFileKey = 'personFileAttachment'; constructor(private apiClient: TransomApiClientService) { this.foiRoutes = this.flattenRoutes(data.routeTree); @@ -21,7 +21,7 @@ export class DataService { getRoute(routeUrl: string): FoiRoute { // Remove any query parameters and (possibly) a leading slash. - const path = (routeUrl || "/").split("?")[0].replace(/^\/+/g, ""); + const path = (routeUrl || '/').split('?')[0].replace(/^\/+/g, ''); return this.foiRoutes.find(r => r.route === path); } @@ -30,8 +30,8 @@ export class DataService { } capitalize(str) { - if (typeof str !== "string") { - return ""; + if (typeof str !== 'string') { + return ''; } return str.charAt(0).toUpperCase() + str.slice(1); } @@ -48,16 +48,16 @@ export class DataService { */ getTopicsObj(about: Object): Array { const topics = []; - for (let key in about) { - if (key !== "child" && about[key]) { + for (const key in about) { + if (key !== 'child' && about[key]) { topics.push(this.capitalize(key)); } } topics .sort() .reverse() - .unshift("topic"); - const topicKey = topics.join(""); + .unshift('topic'); + const topicKey = topics.join(''); return this.getTopics(topicKey); } @@ -69,10 +69,10 @@ export class DataService { } getCurrentState(...dataKeys: string[]): FoiRequest { - const state = this.loadState("foi-request"); + const state = this.loadState('foi-request'); // Ensure that each entry in dataKeys exists before returning. if (dataKeys) { - for (let key of dataKeys) { + for (const key of dataKeys) { state.requestData[key] = state.requestData[key] || {}; } } @@ -90,7 +90,7 @@ export class DataService { foi.requestData[key] = {}; Object.keys(foiForm.value).map(k => (foi.requestData[key][k] = foiForm.value[k])); } - this.saveState("foi-request", foi); + this.saveState('foi-request', foi); return foi; } @@ -98,7 +98,7 @@ export class DataService { return new Observable(observer => { const reader: FileReader = new FileReader(); reader.onload = () => { - try{ + try { sessionStorage.setItem(this.childFileKey, reader.result.toString()); observer.next(true); } catch (err) { @@ -114,9 +114,9 @@ export class DataService { sessionStorage.removeItem(this.childFileKey); } - getStorageErrorText(err: any){ - let result: string = 'Error saving your file, try submitting a smaller file'; - if (err && err.name && err.name === 'QuotaExceededError'){ + getStorageErrorText(err: any) { + let result = 'Error saving your file, try submitting a smaller file'; + if (err && err.name && err.name === 'QuotaExceededError') { result = 'File(s) too large, try submitting smaller files'; } return result; @@ -126,7 +126,7 @@ export class DataService { return new Observable(observer => { const reader: FileReader = new FileReader(); reader.onload = () => { - try{ + try { sessionStorage.setItem(this.personFileKey, reader.result.toString()); observer.next(true); } catch (err) { @@ -143,7 +143,7 @@ export class DataService { } private b64toBlob(b64Data, contentType, sliceSize?): Blob { - contentType = contentType || ""; + contentType = contentType || ''; sliceSize = sliceSize || 512; const byteCharacters = atob(b64Data); @@ -172,8 +172,8 @@ export class DataService { if (!base64) { return null; } - const base64Parts = base64.split(","); - const fileFormat = base64Parts[0].split(";")[1]; + const base64Parts = base64.split(','); + const fileFormat = base64Parts[0].split(';')[1]; const fileContent = base64Parts[1]; const blob = this.b64toBlob(fileContent, fileFormat); return blob; @@ -189,8 +189,8 @@ export class DataService { * @param foiRequest - A structure containing the complete request */ submitRequest(authToken: string, nonce: string, foiRequest: FoiRequest): Observable { - this.apiClient.setHeader("Authorization", "Bearer " + authToken); - this.apiClient.setHeader("captcha-nonce", nonce); + this.apiClient.setHeader('Authorization', 'Bearer ' + authToken); + this.apiClient.setHeader('captcha-nonce', nonce); foiRequest.attachments = []; if (foiRequest.requestData.childInformation) { @@ -198,8 +198,8 @@ export class DataService { const childFile = this.getBlobFrom(this.childFileKey); if (childFile) { const blobFile: BlobFile = { - file: childFile, - filename + file: childFile, + filename }; foiRequest.attachments.push(blobFile); } @@ -209,8 +209,8 @@ export class DataService { const personFile = this.getBlobFrom(this.personFileKey); if (personFile) { const blobFile: BlobFile = { - file: personFile, - filename + file: personFile, + filename }; foiRequest.attachments.push(blobFile); } diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index ca60f611..d139dc11 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -35,6 +35,9 @@ export class KeycloakService { }); } + getToken() { + return sessionStorage.getItem('KC_TOKEN'); + } getDecodedToken(): any { return sessionStorage.getItem('KC_TOKEN') ? From ab5db78815ae4e5df2832e6cc7a474ae08732e26 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sun, 8 Mar 2020 10:37:20 -0700 Subject: [PATCH 022/589] new design added --- .../choose-identity.component.html | 77 +++++++++++++------ .../choose-identity.component.scss | 61 +++++++++++++++ .../choose-identity.component.ts | 42 +++++++--- .../select-about/select-about.component.html | 4 + .../utils-components/base/base.component.html | 2 - .../utils-components/base/base.component.ts | 1 - .../utils-components.module.ts | 22 +++--- 7 files changed, 160 insertions(+), 49 deletions(-) diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/src/app/route-components/choose-identity/choose-identity.component.html index b3dd8710..6315f3f4 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.html +++ b/src/app/route-components/choose-identity/choose-identity.component.html @@ -1,30 +1,56 @@ - + + +
-
-

- To avail documents online , please use your BC Service card to verify your identity.You will be sharing your first name , last name , email with us when you login with BC Service Card -

-

Do you want to login with BC Service Card?

-
- +
+
+
+

+ + + I have a BC Service Card +

+

+ Records will be delivered electronically.No in person walk ins to office to collect records needed +

+

+ Only cards with valid email id will be accepted. +

+
+ +
+
+
-
- +
+
+
+

+ I dont have a BC Service Card +

+

+ + How to obtain a card +

+

+ Without BC Service Card , the records will not be delivered online.The person will have to walk into help desk to collect the records +

+
+ +
+
+
- -
- - Without BC Service card verification , the person has to walk into the office and verify the idenity. the information wont be delivered online - -
+
diff --git a/src/app/route-components/choose-identity/choose-identity.component.scss b/src/app/route-components/choose-identity/choose-identity.component.scss index e69de29b..42a4a70b 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.scss +++ b/src/app/route-components/choose-identity/choose-identity.component.scss @@ -0,0 +1,61 @@ +@import '../../styles/variables.scss'; +// Bootstrap 4: Included imports +@import '../../../../node_modules/bootstrap/scss/functions'; +@import '../../../../node_modules/bootstrap/scss/mixins'; + +.landing-container { + background-color: $color-attention; + border-left: 4px solid $color-secondary; + margin: 1.5rem 1.5rem 0 0; +} + +.landing-content { + padding: 1.2rem; +} + +.landing-header { + font-size: 1.6rem; +} + +.panel-frame { + position: absolute; + top: 200px; + width: 100%; + margin-left: 0; +} +.personInfoPanel { + background-color: $color-primary; + color: white; + border-radius: 20px; + box-shadow: 5px 5px 15px $color-dark; +} + +.personInfoContent { + padding: 15px; +} +.personInfoContent p { + margin-top: 1rem; + line-height: 1.4em; +} + +.personInfoHeader { + font-size: 20px; + text-align: center; + border-bottom: 4px solid $color-secondary; + padding-left: 10px; + padding-right: 10x; +} + +.personInfoFooter { + text-align: center; + padding-left: 10px; + padding-right: 10x; +} + +.personInfoFooter a { + margin-right: 20px; + color: $color-secondary-nav; +} +.personInfoFooter button { + margin-left: 20px; +} diff --git a/src/app/route-components/choose-identity/choose-identity.component.ts b/src/app/route-components/choose-identity/choose-identity.component.ts index 8bad612c..9a1e6868 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.ts +++ b/src/app/route-components/choose-identity/choose-identity.component.ts @@ -3,7 +3,7 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { FormBuilder, Validators } from '@angular/forms'; import { DataService } from 'src/app/services/data.service'; -import {startWith} from "rxjs/operators"; +import {startWith} from 'rxjs/operators'; // import {KeycloakService} from '../../services/keycloak.service'; import { Router } from '@angular/router'; @@ -19,8 +19,8 @@ export class ChooseIdentityComponent implements OnInit { foiRequest: FoiRequest; answerYes: boolean = null; answerReceived: boolean; - continuetext = 'Start your request' - targetKey: string; + continuetext = 'Start your request'; + targetKey = 'choose-idenity'; constructor(private fb: FormBuilder, private dataService: DataService, public router: Router) {} @@ -33,27 +33,47 @@ export class ChooseIdentityComponent implements OnInit { this.foiForm.patchValue(initialValues); this.foiForm.valueChanges.pipe(startWith(initialValues)).subscribe(newValue => { - this.answerReceived = this.answerYes !== null; this.answerYes = newValue.answerYes === 'true'; - if (this.answerYes) { - this.continuetext = 'Login With BC Service Card'; - } else { - this.continuetext = 'Continue without Logging In'; - } + this.answerReceived = this.answerYes !== null; this.base.continueDisabled = !this.answerReceived; }); } }); } doContinue() { + // Update save data & proceed. + const state = this.dataService.setCurrentState( + this.foiRequest, + this.targetKey, + this.foiForm + ); if (this.answerYes) { - this.router.navigateByUrl('signin') + this.router.navigateByUrl('signin'); } else { - sessionStorage.removeItem('KC_TOKEN') + sessionStorage.removeItem('KC_TOKEN'); this.base.goFoiForward(); } // } + + doContinueWithoutLogin() { + const state = this.dataService.setCurrentState( + this.foiRequest, + this.targetKey, + this.foiForm + ); + sessionStorage.removeItem('KC_TOKEN'); + this.base.goFoiForward(); + } + + doLogin() { + const state = this.dataService.setCurrentState( + this.foiRequest, + this.targetKey, + this.foiForm + ); + this.router.navigateByUrl('signin'); + } doGoBack() { this.base.goFoiBack(); } diff --git a/src/app/route-components/select-about/select-about.component.html b/src/app/route-components/select-about/select-about.component.html index a26e3975..8b26538d 100644 --- a/src/app/route-components/select-about/select-about.component.html +++ b/src/app/route-components/select-about/select-about.component.html @@ -4,6 +4,10 @@ (goBack)="doGoBack()" >
+ + You have been successfully logged in using BC Service Card.
+ Please continue with filling the application. +

Who are you requesting records about?

diff --git a/src/app/utils-components/base/base.component.html b/src/app/utils-components/base/base.component.html index ab3b07cf..ab12cda8 100644 --- a/src/app/utils-components/base/base.component.html +++ b/src/app/utils-components/base/base.component.html @@ -10,8 +10,6 @@ [disabled]="continueDisabled" (click)="requestGoForward()" > - - {{ continueText }}
diff --git a/src/app/utils-components/base/base.component.ts b/src/app/utils-components/base/base.component.ts index fc6033a7..c4fe8acf 100644 --- a/src/app/utils-components/base/base.component.ts +++ b/src/app/utils-components/base/base.component.ts @@ -18,7 +18,6 @@ export class BaseComponent implements OnInit { @Input("showInfo") showInfo: boolean = true; @Input("continueText") continueText: string = "Continue"; @Input("continueClass") continueClass: string = ""; - @Input("continueIcon") continueIcon: string = ""; @Input("continueDisabled") continueDisabled: boolean = false; @Input("startupComponent") startupComponent: boolean = false; routeData$: BehaviorSubject; diff --git a/src/app/utils-components/utils-components.module.ts b/src/app/utils-components/utils-components.module.ts index 740940ae..36240b8f 100644 --- a/src/app/utils-components/utils-components.module.ts +++ b/src/app/utils-components/utils-components.module.ts @@ -1,20 +1,20 @@ -import { AlertInfoComponent } from "./alert-info/alert-info.component"; -import { AlertWarningComponent } from "./alert-warning/alert-warning.component"; -import { BaseComponent } from "./base/base.component"; -import { CaptchaComponent } from "./captcha/captcha.component"; -import { FoiFileinputComponent } from "./foi-fileinput/foi-fileinput.component"; -import { FoiValidComponent } from "./foi-valid/foi-valid.component"; -import { CommonModule } from "@angular/common"; -import { ReactiveFormsModule } from "@angular/forms"; -import { NgModule } from "@angular/core"; +import { AlertInfoComponent } from './alert-info/alert-info.component'; +import { AlertWarningComponent } from './alert-warning/alert-warning.component'; +import { BaseComponent } from './base/base.component'; +import { CaptchaComponent } from './captcha/captcha.component'; +import { FoiFileinputComponent } from './foi-fileinput/foi-fileinput.component'; +import { FoiValidComponent } from './foi-valid/foi-valid.component'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { NgModule } from '@angular/core'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { library } from '@fortawesome/fontawesome-svg-core'; -import { faInfoCircle, faExclamationTriangle, faCalendar } from '@fortawesome/free-solid-svg-icons'; +import { faInfoCircle, faExclamationTriangle, faCalendar, faSignInAlt, faQuestionCircle , faIdCardAlt} from '@fortawesome/free-solid-svg-icons'; import { StaticContactBlockComponent } from './static-contact-block/static-contact-block.component'; import { OwlDateTimeModule, OwlNativeDateTimeModule } from 'ng-pick-datetime'; // Add an icon to the library for convenient access in other components -library.add(faInfoCircle, faExclamationTriangle, faCalendar); +library.add(faInfoCircle, faExclamationTriangle, faCalendar, faSignInAlt, faQuestionCircle, faIdCardAlt); @NgModule({ From f7a28e88cd3724814c817a04b477d8bbf4974e66 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sun, 8 Mar 2020 14:23:44 -0700 Subject: [PATCH 023/589] Banner added , fix for not showing values in review --- .../contact-info-options.component.ts | 4 ++ .../select-about/select-about.component.html | 5 +- .../select-about/select-about.component.ts | 46 +++++++++++-------- .../signin/signin.component.ts | 3 +- .../verify-your-identity.component.ts | 11 ++++- src/app/services/data.service.ts | 10 ++++ .../alert-success.component.html | 6 +++ .../alert-success.component.scss | 9 ++++ .../alert-success.component.spec.ts | 25 ++++++++++ .../alert-success/alert-success.component.ts | 15 ++++++ .../utils-components.module.ts | 11 +++-- 11 files changed, 117 insertions(+), 28 deletions(-) create mode 100644 src/app/utils-components/alert-success/alert-success.component.html create mode 100644 src/app/utils-components/alert-success/alert-success.component.scss create mode 100644 src/app/utils-components/alert-success/alert-success.component.spec.ts create mode 100644 src/app/utils-components/alert-success/alert-success.component.ts diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.ts b/src/app/route-components/contact-info-options/contact-info-options.component.ts index 0191c72e..e2998849 100644 --- a/src/app/route-components/contact-info-options/contact-info-options.component.ts +++ b/src/app/route-components/contact-info-options/contact-info-options.component.ts @@ -45,6 +45,9 @@ export class ContactInfoOptionsComponent implements OnInit { // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); + if (isAuthenticated) { + this.foiRequest.requestData.contactInfoOptions.email = token.email; + } this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey], {emitEvent: true}); } @@ -71,6 +74,7 @@ export class ContactInfoOptionsComponent implements OnInit { doContinue() { // Update save data & proceed. + this.foiForm.controls.email.enable() this.dataService.setCurrentState( this.foiRequest, this.targetKey, diff --git a/src/app/route-components/select-about/select-about.component.html b/src/app/route-components/select-about/select-about.component.html index 8b26538d..e0b762b6 100644 --- a/src/app/route-components/select-about/select-about.component.html +++ b/src/app/route-components/select-about/select-about.component.html @@ -4,12 +4,13 @@ (goBack)="doGoBack()" >
- + You have been successfully logged in using BC Service Card.
Please continue with filling the application. -
+

Who are you requesting records about?

+
@@ -55,16 +64,16 @@ diff --git a/src/app/route-components/choose-identity/choose-identity.component.scss b/src/app/route-components/choose-identity/choose-identity.component.scss index 42a4a70b..c4d4db99 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.scss +++ b/src/app/route-components/choose-identity/choose-identity.component.scss @@ -59,3 +59,6 @@ .personInfoFooter button { margin-left: 20px; } +.buttonbar { + margin-top: 20px; +} diff --git a/src/app/route-components/choose-identity/choose-identity.component.ts b/src/app/route-components/choose-identity/choose-identity.component.ts index 9a1e6868..df30a09e 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.ts +++ b/src/app/route-components/choose-identity/choose-identity.component.ts @@ -74,6 +74,7 @@ export class ChooseIdentityComponent implements OnInit { ); this.router.navigateByUrl('signin'); } + doGoBack() { this.base.goFoiBack(); } From 402f2d090d2bda65b10845cad32800719b2f1932 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Mon, 9 Mar 2020 09:04:53 -0700 Subject: [PATCH 025/589] Changes to text in bcsc login page --- .../choose-identity/choose-identity.component.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/src/app/route-components/choose-identity/choose-identity.component.html index 2f8a69d6..e75a36b0 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.html +++ b/src/app/route-components/choose-identity/choose-identity.component.html @@ -14,7 +14,7 @@ Records will be delivered electronically via email if you login with BC Services Card.

Only cards with photo are accepted. - You must update your email address in BC Services Card for electronic delivery of records. Login and navigate to Email Preferences to update your email address. + You must update your email address in BC Services Card for electronic delivery of records. If email address is not updated with BC Services Card, login and navigate to Email Preferences to update your email address.

If it's your first time using your Card to access any online service, there is a one-time security check to verify your identity. @@ -36,10 +36,10 @@ I don't have a BC Service Card

- If you prefer electronic delivery of records via email, you must get a BC Services Card. + If you prefer electronic delivery of records via email, you must login with BC Services Card.

- If you continue without login, you will have to walk-in to help desk and verify your identity in person to receive the records. + If you decide to continue without login, you will have to walk-in to help desk and verify your identity in person to collect the records.

@@ -68,9 +68,11 @@

BC Services Card is government’s trusted way to access online services.

+ How can I get BC Services Card ?

+ How to Login with BC Services Card

diff --git a/src/app/utils-components/utils-components.module.ts b/src/app/utils-components/utils-components.module.ts index 05f1d50e..bd5a8e79 100644 --- a/src/app/utils-components/utils-components.module.ts +++ b/src/app/utils-components/utils-components.module.ts @@ -9,13 +9,13 @@ import { ReactiveFormsModule } from '@angular/forms'; import { NgModule } from '@angular/core'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { library } from '@fortawesome/fontawesome-svg-core'; -import { faInfoCircle, faExclamationTriangle, faCalendar, faSignInAlt, faQuestionCircle , faIdCardAlt, faCheckCircle} from '@fortawesome/free-solid-svg-icons'; +import { faInfoCircle, faExclamationTriangle, faCalendar, faSignInAlt, faQuestionCircle , faIdCardAlt, faCheckCircle, faExternalLinkAlt} from '@fortawesome/free-solid-svg-icons'; import { StaticContactBlockComponent } from './static-contact-block/static-contact-block.component'; import { OwlDateTimeModule, OwlNativeDateTimeModule } from 'ng-pick-datetime'; import { AlertSuccessComponent } from './alert-success/alert-success.component'; // Add an icon to the library for convenient access in other components -library.add(faInfoCircle, faExclamationTriangle, faCalendar, faSignInAlt, faQuestionCircle, faIdCardAlt, faCheckCircle); +library.add(faInfoCircle, faExclamationTriangle, faCalendar, faSignInAlt, faQuestionCircle, faIdCardAlt, faCheckCircle, faExternalLinkAlt); @NgModule({ From 44feb1e14936e8be75da5fb623e9cd2d667c4769 Mon Sep 17 00:00:00 2001 From: Saravan PA Date: Mon, 9 Mar 2020 09:57:06 -0700 Subject: [PATCH 027/589] fix tests --- api/test/emailLayout.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/test/emailLayout.spec.js b/api/test/emailLayout.spec.js index d59b7bf9..0bc14b7f 100644 --- a/api/test/emailLayout.spec.js +++ b/api/test/emailLayout.spec.js @@ -145,7 +145,7 @@ describe('emailLayout', function() { fx.map(fxName => { expect(emailLayout[fxName]).to.exist; }); - expect(Object.keys(emailLayout).length).to.equal(14); + expect(Object.keys(emailLayout).length).to.equal(15); }); it('should render table and headers', function() { From ceaa37d888a7e51a377f209e95affa3c2e2e292c Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Mon, 9 Mar 2020 23:27:42 -0700 Subject: [PATCH 028/589] Changes for logout, readonly DOB, and draft changes for token refresh --- .../review-submit/review-submit.component.ts | 15 ++++- .../verify-your-identity.component.html | 8 +-- .../verify-your-identity.component.ts | 13 ++-- src/app/services/keycloak.service.ts | 61 +++++++++++++++++++ 4 files changed, 85 insertions(+), 12 deletions(-) diff --git a/src/app/route-components/review-submit/review-submit.component.ts b/src/app/route-components/review-submit/review-submit.component.ts index 96650214..038a17ca 100644 --- a/src/app/route-components/review-submit/review-submit.component.ts +++ b/src/app/route-components/review-submit/review-submit.component.ts @@ -32,7 +32,7 @@ export class ReviewSubmitComponent implements OnInit { this.foiRequestPretty = JSON.stringify(this.foiRequest, null, 2); // see if keycloak token is there.set it to authToken - if (this.keycloakService.getDecodedToken() && this.keycloakService.getDecodedToken().email) { + if (this.keycloakService.isAuthenticated()) { this.authToken = this.keycloakService.getToken(); this.captchaComplete = true; this.captchaNonce = '' @@ -59,13 +59,24 @@ export class ReviewSubmitComponent implements OnInit { this.isBusy = true; this.dataService.submitRequest(this.authToken, this.captchaNonce, this.foiRequest).subscribe(result => { this.isBusy = false; - this.base.goFoiForward(); + // If the user is authenticated, logout the user + if(this.keycloakService.isAuthenticated()) { + this.keycloakService.logout() + } else { + this.base.goFoiForward(); + } + }, error => { this.isBusy = false; console.log('Submission failed: ', error); alert('Temporarily unable to submit your request. Please try again in a few minutes.'); this.captchaComponent.forceRefresh(); this.captchaComplete = false; + // if (this.keycloakService.isAuthenticated()) { + // this.keycloakService.logout(); + // } else { + // this.base.goFoiForward(); + // } }); } diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.html b/src/app/route-components/verify-your-identity/verify-your-identity.component.html index f8bb6541..7e1a6202 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.html +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.html @@ -52,7 +52,7 @@

Verify your identity

[form]="foiForm" required="Birth Date is a required field." noFuture="Birth Date must not be in the future." - validDate="Birth Date must be a valid date." + validDate="Birth Date must be a valid date." [dateTimeTrigger]="dt1" > @@ -85,11 +85,11 @@

We need your full name and your birthdate to verify your identity.

What can I request records about?

- You can request records from government ministries or agencies using this service. + You can request records from government ministries or agencies using this service.

- You cannot use this service to request information about Crown corporations, - school districts, health authorities, police, public colleges, and universities, + You cannot use this service to request information about Crown corporations, + school districts, health authorities, police, public colleges, and universities, as these institutions all have their own Freedom of Information (FOI) processes.

diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts index 02d3a2ed..42e4ee4c 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts @@ -17,6 +17,7 @@ export class VerifyYourIdentityComponent implements OnInit { infoBlock: string; includeBirthDate: boolean = false; decodedToken: any; + isAuthenticated: boolean = false; foiForm: FormGroup; @@ -24,15 +25,15 @@ export class VerifyYourIdentityComponent implements OnInit { ngOnInit() { const token = this.keycloak.getDecodedToken(); - const isAuthenticated: boolean = token !== undefined && token.sub !== undefined; + this.isAuthenticated = token !== undefined && token.sub !== undefined; const birthDate = new Date(token.birthDate + 'T00:00:00'); this.foiForm = this.fb.group({ - firstName: [{value: token.firstName, disabled: isAuthenticated}, + firstName: [{value: token.firstName, disabled: this.isAuthenticated}, Validators.compose([Validators.required, Validators.maxLength(255)])], middleName: [null, [Validators.maxLength(255)]], - lastName: [{value: token.lastName , disabled: isAuthenticated }, + lastName: [{value: token.lastName , disabled: this.isAuthenticated }, Validators.compose([Validators.required, Validators.maxLength(255)])], - birthDate: [{value: birthDate , disabled: isAuthenticated }, + birthDate: [{value: birthDate , disabled: this.isAuthenticated }, Validators.compose([Validators.required, Validators.maxLength(12)])], alsoKnownAs: [null, Validators.compose([Validators.maxLength(255)])], businessName: [null, [Validators.maxLength(255)]] @@ -40,7 +41,7 @@ export class VerifyYourIdentityComponent implements OnInit { this.foiRequest = this.dataService.getCurrentState(this.targetKey); - if (isAuthenticated) { + if (this.isAuthenticated) { this.foiRequest.requestData[this.targetKey].firstName = token.firstName; this.foiRequest.requestData[this.targetKey].lastName = token.lastName; this.foiRequest.requestData[this.targetKey].birthDate = token.birthDate; @@ -53,7 +54,7 @@ export class VerifyYourIdentityComponent implements OnInit { if (data) { this.infoBlock = data.infoBlock; this.includeBirthDate = data.includeBirthDate; - if (this.includeBirthDate) { + if (this.includeBirthDate && !this.isAuthenticated) { const currentValue = this.foiForm.get("birthDate").value; this.foiForm.setControl("birthDate", new FormControl(currentValue, [Validators.required, this.base.noFutureValidator])); } diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index d139dc11..e23f0693 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -26,6 +26,7 @@ export class KeycloakService { this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'login-required'}) .success(() => { + this.startRefreshTokenTimer(this.keycloakAuth); sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); resolve(); }) @@ -35,6 +36,41 @@ export class KeycloakService { }); } + startRefreshTokenTimer(kc) { + const expiresIn = (kc.tokenParsed.exp - (new Date().getTime() / 1000) + kc.timeSkew) * 1000; + kc.tokenTimeoutHandle = setTimeout(this.refreshToken, expiresIn); + } + + refreshToken() { + if (!this.keycloakAuth) { + this.keycloakAuth = new Keycloak(config); + this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'check-sso'}) + .success(authenticated => { + if (authenticated) { + this.updateToken(); + } + }); + } else { + this.updateToken(); + } + } + + + updateToken() { + alert('Token expired'); + this.keycloakAuth.updateToken(5) + .then(function(refreshed) { + if (refreshed) { + alert('Token was successfully refreshed'); + } else { + alert('Token is still valid'); + } + }).catch(function() { + alert('Failed to refresh the token, or the session has expired'); + }); + + } + getToken() { return sessionStorage.getItem('KC_TOKEN'); } @@ -50,4 +86,29 @@ export class KeycloakService { }; } + isAuthenticated(): boolean{ + const token = this.getDecodedToken(); + return token !== undefined && token.sub !== undefined; + } + + logout() { + if (this.isAuthenticated()) { + if (!this.keycloakAuth) { + this.keycloakAuth = new Keycloak(config); + this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'check-sso'}) + .success(authenticated => { + if (authenticated) { + this.logoutUser(); + } + }); + } else { + this.logoutUser(); + } + } + } + + logoutUser() { + const redirectUrl = window.location.origin + '/general/submit-complete'; + this.keycloakAuth.logout({ redirectUri: redirectUrl }); + } } From 9717228a31bb6047e70bed4bc6c751f0d42c7bf6 Mon Sep 17 00:00:00 2001 From: Saravan PA Date: Tue, 10 Mar 2020 21:52:50 -0700 Subject: [PATCH 029/589] correcting typo --- api/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/index.js b/api/index.js index 2048db0b..b2d58eae 100644 --- a/api/index.js +++ b/api/index.js @@ -89,7 +89,7 @@ transom credentials:process.env.FOI_KC_CREDENTIALS, secret:process.env.FOI_KC_SECRET, sslRequired:process.env.FOI_KC_SSL_REQUIRED, - publiCclient:process.env.FOI_KC_PUBLIC_CLIENT + publicClient:process.env.FOI_KC_PUBLIC_CLIENT } console.log('kcConfigs'+JSON.stringify(kcConfigs)) From fe2c7fc197b8aa70f275b9fbd99c61437b80612c Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Fri, 13 Mar 2020 16:39:39 -0700 Subject: [PATCH 030/589] Chanegs for KC token refresh --- api/apiAuth.js | 1 - .../verify-your-identity.component.ts | 5 +-- src/app/services/keycloak.service.ts | 40 +++++++++---------- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/api/apiAuth.js b/api/apiAuth.js index e6592489..ce137c67 100644 --- a/api/apiAuth.js +++ b/api/apiAuth.js @@ -42,7 +42,6 @@ function authInit(options) { req.userDetails = {"firstName":decoded.firstName, "lastName":decoded.lastName, "email":decoded.email, - "birthDate":decoded.birthDate } next(); } diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts index 42e4ee4c..f5231934 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts @@ -26,14 +26,13 @@ export class VerifyYourIdentityComponent implements OnInit { ngOnInit() { const token = this.keycloak.getDecodedToken(); this.isAuthenticated = token !== undefined && token.sub !== undefined; - const birthDate = new Date(token.birthDate + 'T00:00:00'); this.foiForm = this.fb.group({ firstName: [{value: token.firstName, disabled: this.isAuthenticated}, Validators.compose([Validators.required, Validators.maxLength(255)])], middleName: [null, [Validators.maxLength(255)]], lastName: [{value: token.lastName , disabled: this.isAuthenticated }, Validators.compose([Validators.required, Validators.maxLength(255)])], - birthDate: [{value: birthDate , disabled: this.isAuthenticated }, + birthDate: [null, Validators.compose([Validators.required, Validators.maxLength(12)])], alsoKnownAs: [null, Validators.compose([Validators.maxLength(255)])], businessName: [null, [Validators.maxLength(255)]] @@ -54,7 +53,7 @@ export class VerifyYourIdentityComponent implements OnInit { if (data) { this.infoBlock = data.infoBlock; this.includeBirthDate = data.includeBirthDate; - if (this.includeBirthDate && !this.isAuthenticated) { + if (this.includeBirthDate) { const currentValue = this.foiForm.get("birthDate").value; this.foiForm.setControl("birthDate", new FormControl(currentValue, [Validators.required, this.base.noFutureValidator])); } diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index e23f0693..273babef 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -26,8 +26,10 @@ export class KeycloakService { this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'login-required'}) .success(() => { + debugger this.startRefreshTokenTimer(this.keycloakAuth); sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); + sessionStorage.setItem('KC_REFRESH' , this.keycloakAuth.refreshToken); resolve(); }) .error(() => { @@ -44,33 +46,28 @@ export class KeycloakService { refreshToken() { if (!this.keycloakAuth) { this.keycloakAuth = new Keycloak(config); - this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'check-sso'}) + this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), refreshToken: sessionStorage.getItem('KC_REFRESH')}) .success(authenticated => { - if (authenticated) { - this.updateToken(); - } + this.keycloakAuth.updateToken(5).success(() => { + console.log('succesfully refreshed token'); + this.startRefreshTokenTimer(this.keycloakAuth); + }).error(() => { + debugger; + console.error('Failed to refresh the token, or the session has expired'); }); + }); } else { - this.updateToken(); + this.keycloakAuth.updateToken(5).success(() => { + console.log('succesfully refreshed token'); + this.startRefreshTokenTimer(this.keycloakAuth); + }).error(() => { + debugger; + console.error('Failed to refresh the token, or the session has expired'); + }); } } - updateToken() { - alert('Token expired'); - this.keycloakAuth.updateToken(5) - .then(function(refreshed) { - if (refreshed) { - alert('Token was successfully refreshed'); - } else { - alert('Token is still valid'); - } - }).catch(function() { - alert('Failed to refresh the token, or the session has expired'); - }); - - } - getToken() { return sessionStorage.getItem('KC_TOKEN'); } @@ -81,8 +78,7 @@ export class KeycloakService { { firstName: '', lastName: '', - email: '', - birthDate: '' + email: '' }; } From 64e8446663290e1ff4d1c740e3d5af490e0546f9 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 14 Mar 2020 11:18:10 -0700 Subject: [PATCH 031/589] configs added to get env variables from dev --- src/proxy.conf.json | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/proxy.conf.json b/src/proxy.conf.json index 65a925be..d0f48793 100644 --- a/src/proxy.conf.json +++ b/src/proxy.conf.json @@ -1,7 +1,12 @@ { - "/api": { - "target": "http://localhost:7085", - "changeOrigin": true, - "secure": false - } -} \ No newline at end of file + "/api/v1/configs": { + "target": "https://foi-requests-dev.pathfinder.gov.bc.ca", + "changeOrigin": true, + "secure": false + }, + "/api": { + "target": "http://localhost:7085", + "changeOrigin": true, + "secure": false + } +} From 5578cda707ef1623b21b1400394879e766025f9c Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 14 Mar 2020 12:23:13 -0700 Subject: [PATCH 032/589] Fix for contact information shown twice when logged in --- api/apiAuth.js | 2 +- api/apiCaptcha.js | 3 ++- api/authCfg.js | 9 ++++----- api/emailLayout.js | 34 +++++++++++++++++++++++----------- api/index.js | 1 - 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/api/apiAuth.js b/api/apiAuth.js index e6592489..09356d62 100644 --- a/api/apiAuth.js +++ b/api/apiAuth.js @@ -9,7 +9,7 @@ var jwksClient = require('jwks-rsa'); function authInit(options) { var client = jwksClient({ - jwksUri: 'https://sso-dev.pathfinder.gov.bc.ca/auth/realms/5k8dbl4h/protocol/openid-connect/certs' + jwksUri: options.JWKS_URI }) const JWT_TOKEN_HEADER = options.CAPTCHA_TOKEN_HEADER || 'Authorization'; // the request header where we expect the jwt token diff --git a/api/apiCaptcha.js b/api/apiCaptcha.js index 871ad24e..91ba37f4 100644 --- a/api/apiCaptcha.js +++ b/api/apiCaptcha.js @@ -202,6 +202,7 @@ function captchaInit(options) { return { valid: false }; } } catch (e) { + console.log(e) return { valid: false }; } } @@ -237,7 +238,7 @@ function captchaInit(options) { if (ret.valid) { next(); } else { - res.send(401, 'Not Authorized'); + res. send(401, 'Not Authorized'); next('Invalid Captcha Token'); } } diff --git a/api/authCfg.js b/api/authCfg.js index af07b70d..7703fb8d 100644 --- a/api/authCfg.js +++ b/api/authCfg.js @@ -1,8 +1,7 @@ 'use strict'; module.exports = { - CAPTCHA_TOKEN_SECRET : process.env.CAPTCHA_TOKEN_SECRET || 'defaultSecret', - CAPTCHA_EXPIRY_MINUTES: '15', - CAPTCHA_TOKEN_HEADER: 'Authorization', - CAPTCHA_NONCE_HEADER: 'captcha-nonce' -}; \ No newline at end of file + CAPTCHA_TOKEN_HEADER: 'Authorization', + CAPTCHA_NONCE_HEADER: 'captcha-nonce', + JWKS_URI: process.env.JWKS_URI +}; diff --git a/api/emailLayout.js b/api/emailLayout.js index a39d197e..1ad5cbef 100644 --- a/api/emailLayout.js +++ b/api/emailLayout.js @@ -50,8 +50,12 @@ module.exports = function EmailLayout() { let result ='' result += this.tableRow('First Name of the Submitter', data.firstName); result += this.tableRow('Last Name of the Submitter', data.lastName); - result += this.tableRow('Email of the Submitter', data.email); - result += this.tableRow('Date Of Birth of the Submitter', data.birthDate); + const anchor = `${ + data.email + }`; + result += this.tableRow('Email of the Submitter', anchor); + // DOB no longer comes from BCSC + //result += this.tableRow('Date Of Birth of the Submitter', data.birthDate); return result } this.general = function(data) { @@ -115,12 +119,20 @@ module.exports = function EmailLayout() { return result; }; - this.personal = function(data) { + this.personal = function(data ,isAuthorised) { + // if isAuthorised , dont print the firstName and LastName let result = this.tableHeader('Contact Information'); - result += this.tableRow( - 'Name', - this.joinBySpace(data.firstName, data.middleName, data.lastName) - ); + if (!isAuthorised) { + result += this.tableRow( + 'Name', + this.joinBySpace(data.firstName, data.middleName, data.lastName) + ); + } else if (data.middleName) { + result += this.tableRow( + 'Middle Name', + this.joinBySpace(data.middleName) + ); + } if (data.alsoKnownAs) { result += this.tableRow('Also Known As', data.alsoKnownAs); } @@ -175,7 +187,7 @@ module.exports = function EmailLayout() { return result; }; - this.contact = function(data) { + this.contact = function(data , isAuthorised) { let result = ''; if (data.phonePrimary) { result += this.tableRow('Phone (primary)', data.phonePrimary); @@ -183,7 +195,7 @@ module.exports = function EmailLayout() { if (data.phoneSecondary) { result += this.tableRow('Phone (secondary)', data.phoneSecondary); } - if (data.email) { + if (data.email && !isAuthorised) { const anchor = `${ data.email }`; @@ -260,8 +272,8 @@ module.exports = function EmailLayout() { // Ministry or Agency content += this.ministry(data.requestData.ministry || {}); // Contact Information - content += this.personal(data.requestData.contactInfo || {}); - content += this.contact(data.requestData.contactInfoOptions || {}); + content += this.personal(data.requestData.contactInfo || {} ,isAuthorised); + content += this.contact(data.requestData.contactInfoOptions || {},isAuthorised); // Adoptive Parents content += this.adoptiveParents(data.requestData.adoptiveParents || {}); // Simple footer diff --git a/api/index.js b/api/index.js index b2d58eae..0a62456d 100644 --- a/api/index.js +++ b/api/index.js @@ -75,7 +75,6 @@ transom.configure(transomSmtp, { transom .initialize(apiDefinition) .then(function(server) { - console.log('--------***s') server.get('/', function(req, res, next) { res.send('FOI Request API Server'); next(); From 3a378de56d354716b47d955b08cfdc5cfc40df72 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 14 Mar 2020 15:10:57 -0700 Subject: [PATCH 033/589] Text changes requested by business --- .../getting-started2/getting-started2.component.html | 3 ++- .../review-submit-complete.component.html | 7 +++---- src/app/services/data.json | 3 --- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/app/route-components/getting-started2/getting-started2.component.html b/src/app/route-components/getting-started2/getting-started2.component.html index b8d5dd23..f7a6e737 100644 --- a/src/app/route-components/getting-started2/getting-started2.component.html +++ b/src/app/route-components/getting-started2/getting-started2.component.html @@ -29,7 +29,8 @@

Are you ready to start your request?

>Health authorities, -
  • Police departments (including the RCMP)
  • +
  • Police departments (including the RCMP)
  • Public colleges and universities
  • Municipalities
  • diff --git a/src/app/route-components/review-submit-complete/review-submit-complete.component.html b/src/app/route-components/review-submit-complete/review-submit-complete.component.html index 5b3ab21b..cb51e34c 100644 --- a/src/app/route-components/review-submit-complete/review-submit-complete.component.html +++ b/src/app/route-components/review-submit-complete/review-submit-complete.component.html @@ -1,10 +1,9 @@
    -

    Your request has been submitted to the central intake team for processing.

    +

    Your request has been submitted to the Consolidated Intake Team for processing.

    - Confirmation will be sent to the email or address you provided within 1-2 business days. This time might be longer - depending on volume. If you have not received a response, please contact us by telephone at 250-387-1321. Please - do not submit a duplicate request. + Confirmation will be sent to the email or address you provided, as soon as possible. + If you have any questions, please contact us by telephone at 250-387-1321. Please do not submit a duplicate request.

    Most requests are filled within 30 business days. We will work with you to provide you with copies of the records. diff --git a/src/app/services/data.json b/src/app/services/data.json index abea3fc7..6c9f18b1 100644 --- a/src/app/services/data.json +++ b/src/app/services/data.json @@ -55,7 +55,6 @@ "ministryCode": "MCF" }, { "value": "adoption", "text": "Adoption", "ministryCode": "MCF" }, - { "value": "communityLiving", "text": "Community Living BC", "ministryCode": "MCF" }, { "value": "anotherTopic", "text": "Other", "ministryCode": null } ], "topicAnother": [ @@ -80,7 +79,6 @@ "ministryCode": "MCF" }, { "value": "adoption", "text": "Adoption", "ministryCode": "MCF" }, - { "value": "communityLiving", "text": "Community Living BC", "ministryCode": "MCF" }, { "value": "anotherTopic", "text": "Other", "ministryCode": null } ], "topicYourselfAnother": [ @@ -105,7 +103,6 @@ "ministryCode": "MCF" }, { "value": "adoption", "text": "Adoption", "ministryCode": "MCF" }, - { "value": "communityLiving", "text": "Community Living BC", "ministryCode": "MCF" }, { "value": "anotherTopic", "text": "Other", "ministryCode": null } ] }, From ec1e823428d339ffef65fb6fddc10811d138b10e Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 14 Mar 2020 15:20:54 -0700 Subject: [PATCH 034/589] guaradian declaration form updated --- .../proof-of-guardianship/proof-of-guardianship.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html b/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html index ebebd6b2..303a93df 100644 --- a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html +++ b/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html @@ -30,7 +30,7 @@

    Do you have permission to access records on beh You must have proof of guardianship to access records about a child. If you don’t have it, please visit our website to view your options. You may complete and sign a Guardian Declaration Form in order to establish your right to access the requested records. From ea93a3a8076eedac4a402585ebb1e1d6b87e1366 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 14 Mar 2020 15:28:32 -0700 Subject: [PATCH 035/589] new links updated --- .../proof-of-guardianship.component.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html b/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html index 303a93df..ae5d3a14 100644 --- a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html +++ b/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html @@ -40,7 +40,7 @@

    Do you have permission to access records on beh which you must fill out and have the person sign. For more information about authorization and consent, please review the resources on our website. @@ -77,7 +77,7 @@

    How do I get permission to access someone’s records?

    • Ministry authorization for release forms @@ -86,7 +86,7 @@

      How do I get permission to access someone’s records?

      For more information about authorization and consent, please review the resources on our website. From 7d875786d8c557fd0a275077d4d044d417e055ce Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 14 Mar 2020 15:47:24 -0700 Subject: [PATCH 036/589] missing birthDate added in review page --- .../review-submit/review-submit.component.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/app/route-components/review-submit/review-submit.component.html b/src/app/route-components/review-submit/review-submit.component.html index df30b768..01b43ce5 100644 --- a/src/app/route-components/review-submit/review-submit.component.html +++ b/src/app/route-components/review-submit/review-submit.component.html @@ -19,6 +19,11 @@

      Review your request

    +
    + + {{ foiRequest.requestData.contactInfo.birthDate | date }} +
    +
    {{ foiRequest.requestData.contactInfoOptions.email }} From 7f0a7c24314e948bf42406105dd5f48e5d3e5ed2 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 14 Mar 2020 16:01:39 -0700 Subject: [PATCH 037/589] changes for business contact helper text added --- .../contact-info/contact-info.component.html | 8 +++++++- .../verify-your-identity.component.html | 4 ++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/app/route-components/contact-info/contact-info.component.html b/src/app/route-components/contact-info/contact-info.component.html index ae29e727..22836789 100644 --- a/src/app/route-components/contact-info/contact-info.component.html +++ b/src/app/route-components/contact-info/contact-info.component.html @@ -44,7 +44,9 @@

    Your name

    -
    +
    +
    +
    Your name +
    diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.html b/src/app/route-components/verify-your-identity/verify-your-identity.component.html index 7e1a6202..80a9299b 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.html +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.html @@ -69,6 +69,10 @@

    Verify your identity

    +
    From 9997b58196587e44ecec1e863e64075980ebdaf7 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Sat, 14 Mar 2020 16:29:58 -0700 Subject: [PATCH 038/589] info on disabled field is adde --- .../verify-your-identity.component.html | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.html b/src/app/route-components/verify-your-identity/verify-your-identity.component.html index 80a9299b..ba0f10c1 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.html +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.html @@ -5,12 +5,15 @@

    Verify your identity

    To ensure personal information is only provided to a person with the right to access it, we need to verify your identity.

    +
    @@ -30,7 +33,7 @@

    Verify your identity

    @@ -71,7 +74,7 @@

    Verify your identity

    From 16b809037a95bc4db613cbc6ba14b6ca8e6645b8 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Sun, 15 Mar 2020 23:15:17 -0700 Subject: [PATCH 039/589] Changes for refresh token --- src/app/services/keycloak.service.ts | 43 +++++++++++++--------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index 273babef..53fd9b06 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -1,8 +1,6 @@ import { Injectable } from '@angular/core'; import * as jwt_decode from 'jwt-decode'; import { default as config } from './keycloak-config.json'; -import {BehaviorSubject, Observable} from 'rxjs'; -import KeyCloak from 'keycloak-js'; import { KeycloakLoginOptions } from 'keycloak-js'; declare var Keycloak: any; @@ -26,7 +24,6 @@ export class KeycloakService { this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'login-required'}) .success(() => { - debugger this.startRefreshTokenTimer(this.keycloakAuth); sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); sessionStorage.setItem('KC_REFRESH' , this.keycloakAuth.refreshToken); @@ -40,33 +37,33 @@ export class KeycloakService { startRefreshTokenTimer(kc) { const expiresIn = (kc.tokenParsed.exp - (new Date().getTime() / 1000) + kc.timeSkew) * 1000; - kc.tokenTimeoutHandle = setTimeout(this.refreshToken, expiresIn); + setTimeout(() => this.refreshToken(), expiresIn); } refreshToken() { if (!this.keycloakAuth) { this.keycloakAuth = new Keycloak(config); - this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), refreshToken: sessionStorage.getItem('KC_REFRESH')}) - .success(authenticated => { - this.keycloakAuth.updateToken(5).success(() => { - console.log('succesfully refreshed token'); - this.startRefreshTokenTimer(this.keycloakAuth); - }).error(() => { - debugger; - console.error('Failed to refresh the token, or the session has expired'); - }); - }); - } else { - this.keycloakAuth.updateToken(5).success(() => { - console.log('succesfully refreshed token'); - this.startRefreshTokenTimer(this.keycloakAuth); - }).error(() => { - debugger; - console.error('Failed to refresh the token, or the session has expired'); + this.keycloakAuth.init( + { + token: sessionStorage.getItem('KC_TOKEN'), + refreshToken: sessionStorage.getItem('KC_REFRESH') + } + ).success(() => { + this.updateToken(); }); - } + } else { + this.updateToken(); } - + } + updateToken() { + this.keycloakAuth.updateToken(-1).success(() => { + this.startRefreshTokenTimer(this.keycloakAuth); + sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); + sessionStorage.setItem('KC_REFRESH' , this.keycloakAuth.refreshToken); + }).error(() => { + console.error('Failed to refresh the token, or the session has expired'); + }); + } getToken() { return sessionStorage.getItem('KC_TOKEN'); From af58d23cd9119f576200ec06ba332ebd77e6f081 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Mon, 16 Mar 2020 11:37:47 -0700 Subject: [PATCH 040/589] fixed dob bug ; fixed link --- .../proof-of-guardianship/proof-of-guardianship.component.html | 2 +- .../verify-your-identity/verify-your-identity.component.ts | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html b/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html index ae5d3a14..3bdaf134 100644 --- a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html +++ b/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html @@ -57,7 +57,7 @@

    What is proof of guardianship?

    Proof of guardianship may include a court order, declaration form, or similar legal document. If you aren’t sure if you have the right documentation, visit our website to find diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts index f5231934..f6d2da20 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.ts @@ -32,8 +32,7 @@ export class VerifyYourIdentityComponent implements OnInit { middleName: [null, [Validators.maxLength(255)]], lastName: [{value: token.lastName , disabled: this.isAuthenticated }, Validators.compose([Validators.required, Validators.maxLength(255)])], - birthDate: [null, - Validators.compose([Validators.required, Validators.maxLength(12)])], + birthDate: [null], alsoKnownAs: [null, Validators.compose([Validators.maxLength(255)])], businessName: [null, [Validators.maxLength(255)]] }); From 4c82db02610973b80fdfbf16a5d280b8c12df5cd Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Mon, 16 Mar 2020 16:51:20 -0700 Subject: [PATCH 041/589] changes for helper text --- .../verify-your-identity.component.html | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.html b/src/app/route-components/verify-your-identity/verify-your-identity.component.html index ba0f10c1..53ef4737 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.html +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.html @@ -69,13 +69,15 @@

    Verify your identity

    [form]="foiForm" maxLength="Business/Organization name is longer than the maximum {requiredLength} characters." > - + - +
    From e2010c87b9bb716061f4c923d761bc2a25f5e96a Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Mon, 16 Mar 2020 22:55:31 -0700 Subject: [PATCH 042/589] Changes to handle BC Services Card with no email address --- api/emailLayout.js | 2 +- .../choose-identity/choose-identity.component.html | 12 +++++++++--- .../choose-identity/choose-identity.component.ts | 7 +++++++ .../select-about/select-about.component.html | 2 +- src/app/route-components/signin/signin.component.ts | 11 ++++++++--- .../verify-your-identity.component.html | 2 +- src/app/services/data.service.ts | 13 +++++++++++++ src/app/services/keycloak.service.ts | 12 ++++++++---- 8 files changed, 48 insertions(+), 13 deletions(-) diff --git a/api/emailLayout.js b/api/emailLayout.js index 1ad5cbef..14c587ac 100644 --- a/api/emailLayout.js +++ b/api/emailLayout.js @@ -242,7 +242,7 @@ module.exports = function EmailLayout() { this.table() if (isAuthorised) { content += this.tableRow( - 'Request Authorisation','BC Service Card' + 'Request Authorisation','BC Services Card' ); content += this.tableRow( diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/src/app/route-components/choose-identity/choose-identity.component.html index 742cfc9c..10eefb5c 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.html +++ b/src/app/route-components/choose-identity/choose-identity.component.html @@ -1,9 +1,15 @@
    + +

    Your request cannot be processed


    + Please update your email address with BC Services Card to electronically receive records.
    + Login and navigate to Email Preferences to update your email address. Close the browser and start the request again, once email address is updated in BC Services Card.

    + If you do not wish to receive records electronically, please Continue without Login +
    -
    +

    @@ -23,7 +29,7 @@

    @@ -33,7 +39,7 @@

    - I don't have a BC Service Card + I don't have a BC Services Card

    If you prefer electronic delivery of records via email, you must login with BC Services Card. diff --git a/src/app/route-components/choose-identity/choose-identity.component.ts b/src/app/route-components/choose-identity/choose-identity.component.ts index df30a09e..0f6f1e04 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.ts +++ b/src/app/route-components/choose-identity/choose-identity.component.ts @@ -21,6 +21,8 @@ export class ChooseIdentityComponent implements OnInit { answerReceived: boolean; continuetext = 'Start your request'; targetKey = 'choose-idenity'; + showEmailAlert = false; + constructor(private fb: FormBuilder, private dataService: DataService, public router: Router) {} @@ -39,6 +41,11 @@ export class ChooseIdentityComponent implements OnInit { }); } }); + // Set the flag to show alert message for email + if (this.dataService.getShowEmailAlert()) { + this.showEmailAlert = true; + this.dataService.removeShowEmailAlert(); + } } doContinue() { // Update save data & proceed. diff --git a/src/app/route-components/select-about/select-about.component.html b/src/app/route-components/select-about/select-about.component.html index e0b762b6..4635ec54 100644 --- a/src/app/route-components/select-about/select-about.component.html +++ b/src/app/route-components/select-about/select-about.component.html @@ -5,7 +5,7 @@ >

    - You have been successfully logged in using BC Service Card.
    + You have been successfully logged in using BC Services Card.
    Please continue with filling the application.

    Who are you requesting records about?

    diff --git a/src/app/route-components/signin/signin.component.ts b/src/app/route-components/signin/signin.component.ts index f5235fe3..78b10b4d 100644 --- a/src/app/route-components/signin/signin.component.ts +++ b/src/app/route-components/signin/signin.component.ts @@ -13,9 +13,14 @@ export class SigninComponent implements OnInit { constructor(private dataService: DataService, private keycloakService: KeycloakService, private router: Router) {} ngOnInit() { - this.keycloakService.init().then(() => { - this.dataService.saveShowBanner(); - this.router.navigateByUrl('personal/select-about'); + this.keycloakService.init().then((authenticated) => { + if (authenticated) { + this.dataService.saveShowBanner(); + this.router.navigateByUrl('personal/select-about'); + } else { + this.dataService.saveShowEmailAlert(); + this.router.navigateByUrl('choose-identity'); + } }); } diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.html b/src/app/route-components/verify-your-identity/verify-your-identity.component.html index 53ef4737..50df8650 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.html +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.html @@ -6,7 +6,7 @@

    Verify your identity

    To ensure personal information is only provided to a person with the right to access it, we need to verify your identity.

    diff --git a/src/app/services/data.service.ts b/src/app/services/data.service.ts index 1024ea1c..904ac81b 100644 --- a/src/app/services/data.service.ts +++ b/src/app/services/data.service.ts @@ -116,10 +116,23 @@ export class DataService { saveShowBanner() { sessionStorage.setItem('showBanner', 'true'); } + removeShowBanner() { sessionStorage.removeItem('showBanner'); } + getShowEmailAlert() { + return sessionStorage.getItem('showEmailAlert'); + } + + saveShowEmailAlert() { + sessionStorage.setItem('showEmailAlert', 'true'); + } + + removeShowEmailAlert() { + sessionStorage.removeItem('showEmailAlert'); + } + removeChildFileAttachment() { sessionStorage.removeItem(this.childFileKey); } diff --git a/src/app/services/keycloak.service.ts b/src/app/services/keycloak.service.ts index 53fd9b06..c573c75a 100644 --- a/src/app/services/keycloak.service.ts +++ b/src/app/services/keycloak.service.ts @@ -24,10 +24,14 @@ export class KeycloakService { this.keycloakAuth.init({token: sessionStorage.getItem('KC_TOKEN'), onLoad: 'login-required'}) .success(() => { - this.startRefreshTokenTimer(this.keycloakAuth); - sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); - sessionStorage.setItem('KC_REFRESH' , this.keycloakAuth.refreshToken); - resolve(); + if (jwt_decode(this.keycloakAuth.token).email) { + this.startRefreshTokenTimer(this.keycloakAuth); + sessionStorage.setItem('KC_TOKEN' , this.keycloakAuth.token); + sessionStorage.setItem('KC_REFRESH' , this.keycloakAuth.refreshToken); + resolve(true); + } else { + resolve(false); + } }) .error(() => { reject(); From f56db88361e4dc68218a4cb23c83c4f97f6c2580 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Wed, 18 Mar 2020 11:09:49 -0700 Subject: [PATCH 043/589] Latest text changes --- api/emailLayout.js | 10 ++-- .../choose-identity.component.html | 56 +++++++++++-------- .../choose-identity.component.scss | 6 ++ .../review-submit.component.html | 6 ++ .../review-submit/review-submit.component.ts | 2 + .../verify-your-identity.component.html | 5 +- 6 files changed, 56 insertions(+), 29 deletions(-) diff --git a/api/emailLayout.js b/api/emailLayout.js index 14c587ac..b2b4d172 100644 --- a/api/emailLayout.js +++ b/api/emailLayout.js @@ -48,12 +48,12 @@ module.exports = function EmailLayout() { this.getAuthorisedDetailsTable = function (data) { let result ='' - result += this.tableRow('First Name of the Submitter', data.firstName); - result += this.tableRow('Last Name of the Submitter', data.lastName); + result += this.tableRow('First Name of requestor', data.firstName); + result += this.tableRow('Last Name of requestor', data.lastName); const anchor = `${ data.email }`; - result += this.tableRow('Email of the Submitter', anchor); + result += this.tableRow('Email of requestor', anchor); // DOB no longer comes from BCSC //result += this.tableRow('Date Of Birth of the Submitter', data.birthDate); return result @@ -242,11 +242,11 @@ module.exports = function EmailLayout() { this.table() if (isAuthorised) { content += this.tableRow( - 'Request Authorisation','BC Services Card' + 'Requestor identity verification','BC Services Card' ); content += this.tableRow( - 'Authorised Details',this.table(this.getAuthorisedDetailsTable(authorisedDetails)) + 'Verified details',this.table(this.getAuthorisedDetailsTable(authorisedDetails)) ); } diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/src/app/route-components/choose-identity/choose-identity.component.html index 10eefb5c..8adf7308 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.html +++ b/src/app/route-components/choose-identity/choose-identity.component.html @@ -10,20 +10,17 @@

    Your request cannot be processed


    +

    To ensure personal information is only provided to a person with the right to access it, we need to verify your identity.

    - Prove your identity using BC Services Card + Verify your identify using BC Services Card

    - Records will be delivered electronically via email if you login with BC Services Card. -

    - Only cards with photo are accepted. - You must update your email address in BC Services Card for electronic delivery of records. If email address is not updated with BC Services Card, login and navigate to Email Preferences to update your email address. -

    - If it's your first time using your card to access any online service, - there is a one-time security check to verify your identity. + If you would like to receive your FOI response package electronically, + you must have a BC Service Card and you must click the link below to verify your identity. + You must also have a registered email address on your BC Service Card.

    @@ -34,18 +31,25 @@

    Your request cannot be processed


    +
    +
    +

    Terms of Use

    +

    Personal information from your BC Service Card is collected under s.26 of the Freedom of Information and Protection of Privacy Act. The information you provide will be only be used in confirming your identity. Upon pressing the [Login with BC Service Card] button you are confirming that you have reviewed this statement. If you have any questions about the collection and use of this information, please contact Information Access Operations at PO Box 9569, Stn Prov Govt, Victoria BC, V8W 9K1 or at 250-387-1321Terms of Use +Personal information from your BC Service Card is collected under s.26 of the Freedom of Information and Protection of Privacy Act. The information you provide will be only be used in confirming your identity. Upon pressing the [Login with BC Service Card] button you are confirming that you have reviewed this statement. If you have any questions about the collection and use of this information, please contact Information Access Operations at PO Box 9569, Stn Prov Govt, Victoria BC, V8W 9K1 or at 250-387-1321

    +
    +

    - I don't have a BC Services Card + Continue without BC Services Card Verification

    - If you prefer electronic delivery of records via email, you must login with BC Services Card. + If you would like to receive a paper copy of your FOI response package, or you don’t have a BC Services Card, you must continue with this FOI request form without BC Services Card verification.

    - If you decide to continue without login, you will have to walk-in to help desk and verify your identity in person to collect the records. + At the end of the FOI process, once your response package is ready for delivery, you will need to go to a ministry office to collect your records and verify your identity in person. Click the link below to continue your FOI request without BC Services Card verification.

    diff --git a/src/app/route-components/choose-identity/choose-identity.component.scss b/src/app/route-components/choose-identity/choose-identity.component.scss index c4d4db99..0f05c39a 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.scss +++ b/src/app/route-components/choose-identity/choose-identity.component.scss @@ -9,6 +9,12 @@ margin: 1.5rem 1.5rem 0 0; } +.terms-container { + background-color: $gray-lighter; + border-left: 4px solid $color-primary; + margin: 1.5rem 1.5rem 0 0; +} + .landing-content { padding: 1.2rem; } diff --git a/src/app/route-components/review-submit/review-submit.component.html b/src/app/route-components/review-submit/review-submit.component.html index 01b43ce5..27d1ede1 100644 --- a/src/app/route-components/review-submit/review-submit.component.html +++ b/src/app/route-components/review-submit/review-submit.component.html @@ -27,6 +27,12 @@

    Review your request

    {{ foiRequest.requestData.contactInfoOptions.email }} +
    + + + Please note: If you would like to update this email address, please Login to your BC Service Card, update the Email Preferences, exit out of this request, and submit a new FOI request. Or you can proceed with this email and this request by hitting Submit below. + +
    diff --git a/src/app/route-components/review-submit/review-submit.component.ts b/src/app/route-components/review-submit/review-submit.component.ts index 038a17ca..23514f91 100644 --- a/src/app/route-components/review-submit/review-submit.component.ts +++ b/src/app/route-components/review-submit/review-submit.component.ts @@ -21,6 +21,7 @@ export class ReviewSubmitComponent implements OnInit { isBusy = false; // during submit! authToken = ''; captchaNonce = '69879887sdsas$#'; + isAuthenticated = false; constructor(private dataService: DataService, private sanitizer: DomSanitizer, private keycloakService: KeycloakService) {} ngOnInit() { @@ -30,6 +31,7 @@ export class ReviewSubmitComponent implements OnInit { } // foiRequestPretty is used for debugging only this.foiRequestPretty = JSON.stringify(this.foiRequest, null, 2); + this.isAuthenticated = this.keycloakService.isAuthenticated(); // see if keycloak token is there.set it to authToken if (this.keycloakService.isAuthenticated()) { diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.html b/src/app/route-components/verify-your-identity/verify-your-identity.component.html index 50df8650..e95ed0c1 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.html +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.html @@ -2,9 +2,12 @@

    Verify your identity

    -

    +

    To ensure personal information is only provided to a person with the right to access it, we need to verify your identity.

    +

    + Enter additional information to complete your profile. Required fields are marked with a red asterisk. Some fields are greyed out and cannot be changed because information has already been verified. +

    From 45f57b08a854877740f72090fe1c9cdc3750e8eb Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Mon, 23 Mar 2020 17:07:46 -0700 Subject: [PATCH 044/589] Fixing some text --- .../choose-identity/choose-identity.component.html | 12 ++++++------ .../review-submit/review-submit.component.html | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/src/app/route-components/choose-identity/choose-identity.component.html index 97d70f72..6bc2fc6a 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.html +++ b/src/app/route-components/choose-identity/choose-identity.component.html @@ -15,12 +15,12 @@

    To ensure personal information is only provided to a person with the right t

    - Verify your identify using BC Services Card + Verify your identity using BC Services Card

    If you would like to receive your FOI response package electronically, - you must have a BC Service Card and you must click the link below to verify your identity. - You must also have a registered email address on your BC Service Card. + you must have a BC Services Card and you must click the link below to verify your identity. + You must also have a registered email address on your BC Services Card.

    @@ -35,7 +35,7 @@

    To ensure personal information is only provided to a person with the right t

    Terms of Use

    - Personal information from your BC Service Card is collected under s.26 of the Freedom of Information and Protection of Privacy Act. The information you provide will be only be used in confirming your identity. Upon pressing the [Login with BC Service Card] button you are confirming that you have reviewed this statement. If you have any questions about the collection and use of this information, please contact Information Access Operations at PO Box 9569, Stn Prov Govt, Victoria BC, V8W 9K1 or at 250-387-1321 + Personal information from your BC Services Card is collected under s.26 of the Freedom of Information and Protection of Privacy Act. The information you provide will be only be used in confirming your identity. Upon pressing the [Login with BC Services Card] button you are confirming that you have reviewed this statement. If you have any questions about the collection and use of this information, please contact Information Access Operations at PO Box 9569, Stn Prov Govt, Victoria BC, V8W 9K1 or at 250-387-1321

    @@ -77,12 +77,12 @@

    More information

    What is a BC Services Card ?

    How do I login with my BC Services Card ?

    I don't have a BC Services Card

    -

    To check whether your BC Service Card has a verified email address:

    +

    To check whether your BC Services Card has a verified email address:

    • Login to your BC Services Card
    • Look under Email Preferences
    -

    To update or add an email address to your BC Service Card:

    +

    To update or add an email address to your BC Services Card:

    • Login to your BC Services Card
    • Look under Email Preferences
    • diff --git a/src/app/route-components/review-submit/review-submit.component.html b/src/app/route-components/review-submit/review-submit.component.html index 27d1ede1..a084c225 100644 --- a/src/app/route-components/review-submit/review-submit.component.html +++ b/src/app/route-components/review-submit/review-submit.component.html @@ -30,7 +30,7 @@

      Review your request

      - Please note: If you would like to update this email address, please Login to your BC Service Card, update the Email Preferences, exit out of this request, and submit a new FOI request. Or you can proceed with this email and this request by hitting Submit below. + Please note: If you would like to update this email address, please Login to your BC Services Card, update the Email Preferences, exit out of this request, and submit a new FOI request. Or you can proceed with this email and this request by hitting Submit below.
    From 3c09ea8d0297c293917c75fbccf7dcf2b7ad4477 Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Mon, 23 Mar 2020 17:17:01 -0700 Subject: [PATCH 045/589] Fixing some text --- .../choose-identity.component.html | 1 + .../contact-info-options.component.html | 24 +++++++++++-------- .../contact-info-options.component.ts | 7 +++--- .../review-submit.component.html | 6 ----- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/src/app/route-components/choose-identity/choose-identity.component.html index 6bc2fc6a..c87f4129 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.html +++ b/src/app/route-components/choose-identity/choose-identity.component.html @@ -38,6 +38,7 @@

    Terms of Use

    Personal information from your BC Services Card is collected under s.26 of the Freedom of Information and Protection of Privacy Act. The information you provide will be only be used in confirming your identity. Upon pressing the [Login with BC Services Card] button you are confirming that you have reviewed this statement. If you have any questions about the collection and use of this information, please contact Information Access Operations at PO Box 9569, Stn Prov Govt, Victoria BC, V8W 9K1 or at 250-387-1321

    +
    diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.html b/src/app/route-components/contact-info-options/contact-info-options.component.html index 69dcc974..5b4e86c1 100644 --- a/src/app/route-components/contact-info-options/contact-info-options.component.html +++ b/src/app/route-components/contact-info-options/contact-info-options.component.html @@ -6,7 +6,7 @@ the status of your request or potential fees relating to processing your request.

    - +

    Ways to get in touch with you

    Ways to get in touch with you records, we need AT LEAST ONE form of contact information.

    - +
    @@ -28,7 +28,7 @@

    Ways to get in touch with you

    - +
    Ways to get in touch with you
    -
    Ways to get in touch with you +
    + + + Please note: If you would like to update this email address, please Login to your BC Services Card, update the Email Preferences, exit out of this request, and submit a new FOI request. Or you can proceed with this email and this request by hitting Continue below. + +
    @@ -65,7 +70,7 @@

    Ways to get in touch with you

    - +
    Ways to get in touch with you
    - +
    Ways to get in touch with you
    - +
    Ways to get in touch with you
    - +
    Ways to get in touch with you
    - + - \ No newline at end of file diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.ts b/src/app/route-components/contact-info-options/contact-info-options.component.ts index e2998849..faa16920 100644 --- a/src/app/route-components/contact-info-options/contact-info-options.component.ts +++ b/src/app/route-components/contact-info-options/contact-info-options.component.ts @@ -25,15 +25,16 @@ export class ContactInfoOptionsComponent implements OnInit { foiRequest: FoiRequest; targetKey: string = 'contactInfoOptions'; + isAuthenticated:boolean = false; constructor(private fb: FormBuilder, private dataService: DataService, private keycloak: KeycloakService) {} ngOnInit() { // Update email if the user is authenticated const token = this.keycloak.getDecodedToken(); - const isAuthenticated: boolean = (token !== undefined && token.sub !== undefined); + this.isAuthenticated = (token !== undefined && token.sub !== undefined); this.foiForm = this.fb.group({ - email: [{value: token.email, disabled: isAuthenticated}], + email: [{value: token.email, disabled: this.isAuthenticated}], phonePrimary: [null], phoneSecondary: [null], address: [null], @@ -45,7 +46,7 @@ export class ContactInfoOptionsComponent implements OnInit { // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); - if (isAuthenticated) { + if (this.isAuthenticated) { this.foiRequest.requestData.contactInfoOptions.email = token.email; } this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey], {emitEvent: true}); diff --git a/src/app/route-components/review-submit/review-submit.component.html b/src/app/route-components/review-submit/review-submit.component.html index a084c225..01b43ce5 100644 --- a/src/app/route-components/review-submit/review-submit.component.html +++ b/src/app/route-components/review-submit/review-submit.component.html @@ -27,12 +27,6 @@

    Review your request

    {{ foiRequest.requestData.contactInfoOptions.email }} -
    - - - Please note: If you would like to update this email address, please Login to your BC Services Card, update the Email Preferences, exit out of this request, and submit a new FOI request. Or you can proceed with this email and this request by hitting Submit below. - -
    From a1c8908dd0c271b826ce48915ed39339c9179538 Mon Sep 17 00:00:00 2001 From: saravanpa-aot Date: Tue, 24 Mar 2020 08:05:49 -0700 Subject: [PATCH 046/589] Changes from the demo --- .../choose-identity/choose-identity.component.html | 2 +- .../contact-info-options/contact-info-options.component.html | 2 +- .../contact-info-options/contact-info-options.component.ts | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/src/app/route-components/choose-identity/choose-identity.component.html index c87f4129..5ebd62ad 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.html +++ b/src/app/route-components/choose-identity/choose-identity.component.html @@ -33,7 +33,7 @@

    To ensure personal information is only provided to a person with the right t

    -

    Terms of Use

    +

    Information Collection Notice

    Personal information from your BC Services Card is collected under s.26 of the Freedom of Information and Protection of Privacy Act. The information you provide will be only be used in confirming your identity. Upon pressing the [Login with BC Services Card] button you are confirming that you have reviewed this statement. If you have any questions about the collection and use of this information, please contact Information Access Operations at PO Box 9569, Stn Prov Govt, Victoria BC, V8W 9K1 or at 250-387-1321

    diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.html b/src/app/route-components/contact-info-options/contact-info-options.component.html index 5b4e86c1..ae8be001 100644 --- a/src/app/route-components/contact-info-options/contact-info-options.component.html +++ b/src/app/route-components/contact-info-options/contact-info-options.component.html @@ -42,7 +42,7 @@

    Ways to get in touch with you

    diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.ts b/src/app/route-components/contact-info-options/contact-info-options.component.ts index faa16920..a7d201a2 100644 --- a/src/app/route-components/contact-info-options/contact-info-options.component.ts +++ b/src/app/route-components/contact-info-options/contact-info-options.component.ts @@ -26,6 +26,7 @@ export class ContactInfoOptionsComponent implements OnInit { foiRequest: FoiRequest; targetKey: string = 'contactInfoOptions'; isAuthenticated:boolean = false; + tip = '' constructor(private fb: FormBuilder, private dataService: DataService, private keycloak: KeycloakService) {} @@ -43,7 +44,7 @@ export class ContactInfoOptionsComponent implements OnInit { province: [null], country: [null] }); - + this.tip = this.isAuthenticated ? '' : 'Email address is required for electronic delivery' ; // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); if (this.isAuthenticated) { From 4c07cb4b025349576a9e1222d38d544aa3f437cc Mon Sep 17 00:00:00 2001 From: Sumesh Punakkal Kariyil Date: Tue, 24 Mar 2020 19:44:10 -0700 Subject: [PATCH 047/589] Text and label changes --- .../choose-identity.component.html | 82 +++++++++++-------- .../choose-identity.component.scss | 14 ++-- .../contact-info-options.component.html | 12 ++- .../select-about/select-about.component.html | 3 +- .../verify-your-identity.component.html | 8 +- .../alert-success.component.html | 2 +- .../alert-success.component.scss | 5 ++ 7 files changed, 69 insertions(+), 57 deletions(-) diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/src/app/route-components/choose-identity/choose-identity.component.html index 5ebd62ad..256da2ce 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.html +++ b/src/app/route-components/choose-identity/choose-identity.component.html @@ -2,15 +2,17 @@
    -

    Your request cannot be processed


    - Please update your email address with BC Services Card to electronically receive records.
    - Login and navigate to Email Preferences to update your email address. Close the browser and start the request again, once email address is updated in BC Services Card.

    - If you do not wish to receive records electronically, please Continue without Login +

    Unfortunately your identity has not been verified.

    +

    If you would like to receive your FOI response package electronically:

    +
      +
    • You must add a registered email address on your BC Services Card
    • +
    • Then you must close this window and submit a new request
    • +
    +

    Follow the instructions in More Information (on the right hand side) to add an email address to your BC Services Card.

    -

    To ensure personal information is only provided to a person with the right to access it, we need to verify your identity.

    @@ -18,10 +20,19 @@

    To ensure personal information is only provided to a person with the right t Verify your identity using BC Services Card

    - If you would like to receive your FOI response package electronically, - you must have a BC Services Card and you must click the link below to verify your identity. - You must also have a registered email address on your BC Services Card. + If you would like to receive your FOI response package electronically:

    +
      +
    • You must have a BC Services Card with a photo
    • +
    • You must click the link below to verify your identity
    • +
    • You must have a registered email address on your BC Services Card
    • +
    +
    +

    Information Collection Notice

    +

    + Personal information from your BC Services Card is collected under s.26 of the Freedom of Information and Protection of Privacy Act. The information you provide will be only be used in confirming your identity. Upon pressing the [Login with BC Services Card] button you are confirming that you have reviewed this statement. If you have any questions about the collection and use of this information, please contact Information Access Operations at PO Box 9569, Stn Prov Govt, Victoria BC, V8W 9K1 or at 250-387-1321 +

    +

    -
    -
    -

    Information Collection Notice

    -

    - Personal information from your BC Services Card is collected under s.26 of the Freedom of Information and Protection of Privacy Act. The information you provide will be only be used in confirming your identity. Upon pressing the [Login with BC Services Card] button you are confirming that you have reviewed this statement. If you have any questions about the collection and use of this information, please contact Information Access Operations at PO Box 9569, Stn Prov Govt, Victoria BC, V8W 9K1 or at 250-387-1321 -

    -
    -
    +
    @@ -47,11 +51,15 @@

    Information Collection Notice

    Continue without BC Services Card Verification

    - If you would like to receive a paper copy of your FOI response package, or you don’t have a BC Services Card, you must continue with this FOI request form without BC Services Card verification. -

    -

    - At the end of the FOI process, once your response package is ready for delivery, you will need to go to a ministry office to collect your records and verify your identity in person. Click the link below to continue your FOI request without BC Services Card verification. + If you would like to receive a paper copy of your FOI response package,
    + OR you don’t have a BC Services Card with a photo:

    + +
      +
    • You must continue with this FOI request form without BC Services Card verification
    • +
    • At the end of the FOI process, once your response package is ready for delivery, you will need to go to a ministry office to collect your records and verify your identity in person
    • +
    +
    diff --git a/src/app/route-components/choose-identity/choose-identity.component.scss b/src/app/route-components/choose-identity/choose-identity.component.scss index 0f05c39a..769634a4 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.scss +++ b/src/app/route-components/choose-identity/choose-identity.component.scss @@ -6,13 +6,7 @@ .landing-container { background-color: $color-attention; border-left: 4px solid $color-secondary; - margin: 1.5rem 1.5rem 0 0; -} - -.terms-container { - background-color: $gray-lighter; - border-left: 4px solid $color-primary; - margin: 1.5rem 1.5rem 0 0; + margin: 1.5rem 0 0 0; } .landing-content { @@ -68,3 +62,9 @@ .buttonbar { margin-top: 20px; } +.information { + font-size: small; +} +.email-update-box { + margin: 0 0 3em 0; +} \ No newline at end of file diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.html b/src/app/route-components/contact-info-options/contact-info-options.component.html index ae8be001..5a1fca51 100644 --- a/src/app/route-components/contact-info-options/contact-info-options.component.html +++ b/src/app/route-components/contact-info-options/contact-info-options.component.html @@ -1,18 +1,16 @@
    -

    +

    Ways to get in touch with you

    - * Please note that in order to follow up with you and deliver your - records, we need AT LEAST ONE form of contact information. + * Please note that in order to follow up with you and deliver your + records, we need AT LEAST ONE form of contact information.

    @@ -52,7 +50,7 @@

    Ways to get in touch with you

    - Please note: If you would like to update this email address, please Login to your BC Services Card, update the Email Preferences, exit out of this request, and submit a new FOI request. Or you can proceed with this email and this request by hitting Continue below. + Please note: If you would like to change this email address, please Login to your BC Services Card, update the Email Preferences, exit out of this request, and submit a new FOI request.
    diff --git a/src/app/route-components/select-about/select-about.component.html b/src/app/route-components/select-about/select-about.component.html index 4635ec54..a9cfcf92 100644 --- a/src/app/route-components/select-about/select-about.component.html +++ b/src/app/route-components/select-about/select-about.component.html @@ -5,8 +5,7 @@ >
    - You have been successfully logged in using BC Services Card.
    - Please continue with filling the application. + Thank you for verifying your identity using BC Services Card.

    Who are you requesting records about?

    diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.html b/src/app/route-components/verify-your-identity/verify-your-identity.component.html index e95ed0c1..ebc37f5b 100644 --- a/src/app/route-components/verify-your-identity/verify-your-identity.component.html +++ b/src/app/route-components/verify-your-identity/verify-your-identity.component.html @@ -1,15 +1,13 @@
    -

    Verify your identity

    + +

    Complete your profile

    To ensure personal information is only provided to a person with the right to access it, we need to verify your identity.

    -

    - Enter additional information to complete your profile. Required fields are marked with a red asterisk. Some fields are greyed out and cannot be changed because information has already been verified. -

    diff --git a/src/app/utils-components/alert-success/alert-success.component.html b/src/app/utils-components/alert-success/alert-success.component.html index 71c1edce..74f20c8f 100644 --- a/src/app/utils-components/alert-success/alert-success.component.html +++ b/src/app/utils-components/alert-success/alert-success.component.html @@ -1,6 +1,6 @@ -
    +
    + + + + +
    +
    Date: Sat, 16 May 2020 08:11:36 -0700 Subject: [PATCH 093/589] Update review-submit.component.html --- .../route-components/review-submit/review-submit.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/route-components/review-submit/review-submit.component.html b/src/app/route-components/review-submit/review-submit.component.html index 885d93d4..66acf6b9 100644 --- a/src/app/route-components/review-submit/review-submit.component.html +++ b/src/app/route-components/review-submit/review-submit.component.html @@ -10,7 +10,7 @@

    Review your request

    {{ foiRequest.requestData.contactInfo.firstName }} -
    {{authToken? 'Given Names':'First'}}
    +
    {{authToken? 'Given':'First'}}
    {{ foiRequest.requestData.contactInfo.lastName }} From 4963546057d340fc5911de2a505ab2c1eaebcec2 Mon Sep 17 00:00:00 2001 From: MatthewPMorris <47045391+MatthewPMorris@users.noreply.github.com> Date: Mon, 30 Nov 2020 12:37:19 -0800 Subject: [PATCH 094/589] Update data.json ALtering to reflect new ministry names --- src/app/services/data.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/app/services/data.json b/src/app/services/data.json index 6c9f18b1..8a01897d 100644 --- a/src/app/services/data.json +++ b/src/app/services/data.json @@ -1,16 +1,16 @@ { "referenceData": { "ministries": [ - { "code": "AEST", "name": "Advanced Education, Skills and Training" }, - { "code": "AGRI", "name": "Agriculture" }, - { "code": "AG", "name": "Attorney General" }, + { "code": "AEST", "name": "Advanced Education and Skills and Training" }, + { "code": "AGRI", "name": "Agriculture, Food, and Fisheries" }, + { "code": "AG", "name": "Attorney General (and Minister Responsible for Housing)" }, { "code": "PSA", "name": "BC Public Service Agency" }, { "code": "MCF", "name": "Children and Family Development" }, { "code": "CITZ", "name": "Citizens’ Services" }, - { "code": "EMBC", "name": "Emergency Management BC" }, { "code": "EDUC", "name": "Education" }, - { "code": "EMPR", "name": "Energy, Mines and Petroleum Resources" }, - { "code": "ENV", "name": "Environment and Climate Change Strategy" }, + { "code": "EMBC", "name": "Emergency Management BC" }, + { "code": "EMPR", "name": "Energy, Mines and Low Carbon Innovation (and Minister Responsible for the Consular Corps of British Columbia)" }, + { "code": "ENV", "name": "Environment and Climate Change Strategy (and Minister Responsible for Translink)" }, { "code": "EAO", "name": "Environmental Assessment Office" }, { "code": "FIN", "name": "Finance" }, { @@ -21,16 +21,16 @@ "code": "GCPE", "name": "Government Communications and Public Engagement" }, - { "code": "HLTH", "name": "Health" }, + { "code": "HLTH", "name": "Health (and Minister Responsible for Francophone Affairs)" }, { "code": "IRR", "name": "Indigenous Relations and Reconciliation" }, - { "code": "JTT", "name": "Jobs, Economic Development and Competitiveness" }, + { "code": "JTT", "name": "Jobs, Economic Recovery and Innovation" }, { "code": "LBR", "name": "Labour" }, { "code": "MMHA", "name": "Mental Health and Addictions" }, - { "code": "MAH", "name": "Municipal Affairs and Housing" }, + { "code": "MAH", "name": "Municipal Affairs" }, { "code": "PREM", "name": "Office of the Premier" }, { "code": "PSSG", "name": "Public Safety and Solicitor General" }, { "code": "SDPR", "name": "Social Development and Poverty Reduction" }, - { "code": "TAC", "name": "Tourism, Arts and Culture" }, + { "code": "TAC", "name": "Tourism, Arts, Culture and Sport" }, { "code": "TRAN", "name": "Transportation and Infrastructure" } ], "topicYourself": [ From 260ee6e857ab77e1bdcd7fa4059d2a7c7871c41a Mon Sep 17 00:00:00 2001 From: MatthewPMorris <47045391+MatthewPMorris@users.noreply.github.com> Date: Mon, 30 Nov 2020 12:52:36 -0800 Subject: [PATCH 095/589] Update MockClasses.ts Update getMinistries() for new ministry names --- src/app/MockClasses.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/MockClasses.ts b/src/app/MockClasses.ts index 13721ddc..96be635b 100644 --- a/src/app/MockClasses.ts +++ b/src/app/MockClasses.ts @@ -71,9 +71,9 @@ export class MockDataService { getMinistries(): Observable { return of([ - { code: "AEST", name: "Advanced Education, Skills and Training" }, - { code: "AGRI", name: "Agriculture" }, - { code: "AG", name: "Attorney General" }, + { code: "AEST", name: "Advanced Education and Skills and Training" }, + { code: "AGRI", name: "Agriculture, Food, and Fisheries" }, + { code: "AG", name: "Attorney General (and Minister Responsible for Housing)" }, { code: "PSSG", name: "Public Safety and Solicitor General" } ]); } From 347697d3ffc8ae9356363e7e8e40c60c53af0cf0 Mon Sep 17 00:00:00 2001 From: Burak Akcen <28536163+burock7@users.noreply.github.com> Date: Wed, 13 Jan 2021 19:10:06 -0800 Subject: [PATCH 096/589] Update index.html Updating the snowplow tracker code with vE.2.14.0 --- src/index.html | 45 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/index.html b/src/index.html index 9630c033..5ea6fc0e 100644 --- a/src/index.html +++ b/src/index.html @@ -10,29 +10,28 @@ - - - - + +;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[]; + p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments) + };p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1; + n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","https://www2.gov.bc.ca/StaticWebResources/static/sp/sp-2-14-0.js","snowplow")); +var collector = 'spt.apps.gov.bc.ca'; + window.snowplow('newTracker','rt',collector, { + appId: "Snowplow_standalone", + cookieLifetime: 86400 * 548, + platform: 'web', + post: true, + forceSecureTracker: true, + contexts: { + webPage: true, + performanceTiming: true + } + }); + window.snowplow('enableActivityTracking', 30, 30); // Ping every 30 seconds after 30 seconds + window.snowplow('enableLinkClickTracking'); + window.snowplow('trackPageView'); + +
    From 949c67aa4023f46f3dfe8f0a482541bf9ba0ae28 Mon Sep 17 00:00:00 2001 From: Burak Akcen <28536163+burock7@users.noreply.github.com> Date: Thu, 14 Jan 2021 13:28:24 -0800 Subject: [PATCH 097/589] Update index.html Snowplow code update --- src/index.html | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/index.html b/src/index.html index 9630c033..403acf64 100644 --- a/src/index.html +++ b/src/index.html @@ -10,28 +10,29 @@ - + - + From babfcdd716d02ac58db3e0ee4809237cac752f6c Mon Sep 17 00:00:00 2001 From: Burak Akcen <28536163+burock7@users.noreply.github.com> Date: Wed, 20 Jan 2021 09:58:47 -0800 Subject: [PATCH 098/589] Update choose-identity.component.html removing the phrase "with a word" from BC Services Card sentences --- .../choose-identity/choose-identity.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/src/app/route-components/choose-identity/choose-identity.component.html index cd802ed8..8e0f0825 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.html +++ b/src/app/route-components/choose-identity/choose-identity.component.html @@ -23,7 +23,7 @@ To receive your FOI response package electronically:

      -
    • You must have a BC Services Card with a photo
    • +
    • You must have a BC Services Card
    • You must have an email address on your BC Services Card account

    @@ -57,7 +57,7 @@

    Information Collection Notice

    If you would like to receive a paper copy of your FOI response package,
    - OR you don’t have a BC Services Card with a photo: + OR you don’t have a BC Services Card:

      From 2aa0f71090840dd36ed9559cbba77135f1fc11ed Mon Sep 17 00:00:00 2001 From: Burak Akcen <28536163+burock7@users.noreply.github.com> Date: Wed, 20 Jan 2021 10:04:58 -0800 Subject: [PATCH 099/589] Update choose-identity.component.html Updating the links to verification and help --- .../choose-identity/choose-identity.component.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/src/app/route-components/choose-identity/choose-identity.component.html index 8e0f0825..e6319efc 100644 --- a/src/app/route-components/choose-identity/choose-identity.component.html +++ b/src/app/route-components/choose-identity/choose-identity.component.html @@ -27,7 +27,7 @@
    • You must have an email address on your BC Services Card account

    - First time BC Services Card users: You need to verify your identity. Please set up your email when prompted. + First time BC Services Card users: You need to verify your identity. Please set up your email when prompted.

    To add or change your email address: Go to ‘Manage Account’ in the BC Services Card application, then choose ‘Email Preferences’ to add an email address. @@ -115,9 +115,9 @@

    More information

    Click the links below to learn more about the BC Services Card

    -

    What is a BC Services Card?

    -

    How do I log in with my BC Services Card?

    -

    How do I get a BC Services Card?

    +

    What is a BC Services Card?

    +

    How do I log in with my BC Services Card?

    +

    How do I get a BC Services Card?

    From b169093aa39210b5bf26964a13b31fcc68eddcc8 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Tue, 16 Feb 2021 11:30:07 -0800 Subject: [PATCH 100/589] Update git ignore --- .gitignore | 2 ++ csr_details.txt | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 csr_details.txt diff --git a/.gitignore b/.gitignore index b5175a57..b938bb81 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ testem.log # System Files .DS_Store Thumbs.db +*.pem +*.key diff --git a/csr_details.txt b/csr_details.txt new file mode 100644 index 00000000..0c3a0973 --- /dev/null +++ b/csr_details.txt @@ -0,0 +1,28 @@ +# Run the following command to (re)generate a CSR +# openssl req -new -sha256 -nodes \ +# -out foi-request-form.gov.bc.ca.csr -newkey rsa:2048 \ +# -keyout foi-request-form.gov.bc.ca.key \ +# -config <(cat csr_details.txt) +[req] +default_bits=2048 +prompt=no +default_md=sha256 +req_extensions=req_ext +distinguished_name=dn + +[dn] +C=CA +ST=British Columbia +L=Victoria +O=Government of the Province of British Columbia +OU=Citizens' Services +CN=foi-request-form.gov.bc.ca +emailAddress=jason.leach@gov.bc.ca + +[req_ext] +subjectAltName=@alt_names + +[alt_names] +DNS.1=foi-request-form.gov.bc.ca +DNS.2=dev.foi-request-form.gov.bc.ca +DNS.3=test.foi-request-form.gov.bc.ca From 16fc4aa2382a4a64a11636c5e6f2133b4f3ae9c7 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Tue, 16 Feb 2021 11:54:43 -0800 Subject: [PATCH 101/589] Project org --- .gitignore | 3 +++ angular.json => web/angular.json | 0 package-lock.json => web/package-lock.json | 0 package.json => web/package.json | 0 {src => web/src}/.prettierrc | 0 {src => web/src}/app/MockClasses.ts | 0 {src => web/src}/app/app-routing.module.ts | 0 {src => web/src}/app/app.component.html | 0 {src => web/src}/app/app.component.scss | 0 {src => web/src}/app/app.component.spec.ts | 0 {src => web/src}/app/app.component.ts | 0 {src => web/src}/app/app.module.ts | 0 .../src}/app/core-header/core-header.component.html | 0 .../src}/app/core-header/core-header.component.scss | 0 .../app/core-header/core-header.component.spec.ts | 0 .../src}/app/core-header/core-header.component.ts | 0 {src => web/src}/app/foi-router.service.spec.ts | 0 {src => web/src}/app/foi-router.service.ts | 0 {src => web/src}/app/footer/footer.component.html | 0 {src => web/src}/app/footer/footer.component.scss | 0 .../src}/app/footer/footer.component.spec.ts | 0 {src => web/src}/app/footer/footer.component.ts | 0 {src => web/src}/app/models/FoiRequest.ts | 0 {src => web/src}/app/models/FoiRoute.ts | 0 {src => web/src}/app/models/user.ts | 0 .../app/progress-bar/progress-bar.component.html | 0 .../app/progress-bar/progress-bar.component.scss | 0 .../app/progress-bar/progress-bar.component.spec.ts | 0 .../src}/app/progress-bar/progress-bar.component.ts | 0 .../adoptive-parents.component.html | 0 .../adoptive-parents.component.scss | 0 .../adoptive-parents.component.spec.ts | 0 .../adoptive-parents/adoptive-parents.component.ts | 0 .../another-information.component.html | 0 .../another-information.component.scss | 0 .../another-information.component.spec.ts | 0 .../another-information.component.ts | 0 .../child-information.component.html | 0 .../child-information.component.scss | 0 .../child-information.component.spec.ts | 0 .../child-information.component.ts | 0 .../choose-identity/choose-identity.component.html | 0 .../choose-identity/choose-identity.component.scss | 0 .../choose-identity.component.spec.ts | 0 .../choose-identity/choose-identity.component.ts | 0 .../contact-info-options.component.html | 0 .../contact-info-options.component.scss | 0 .../contact-info-options.component.spec.ts | 0 .../contact-info-options.component.ts | 0 .../contact-info/contact-info.component.html | 0 .../contact-info/contact-info.component.scss | 0 .../contact-info/contact-info.component.spec.ts | 0 .../contact-info/contact-info.component.ts | 0 .../description-timeframe.component.html | 0 .../description-timeframe.component.scss | 0 .../description-timeframe.component.spec.ts | 0 .../description-timeframe.component.ts | 0 .../general-info/general-info.component.html | 0 .../general-info/general-info.component.scss | 0 .../general-info/general-info.component.ts | 0 .../general-select-ministry.component.html | 0 .../general-select-ministry.component.scss | 0 .../general-select-ministry.component.spec.ts | 0 .../general-select-ministry.component.ts | 0 .../getting-started1.component.html | 0 .../getting-started1.component.scss | 0 .../getting-started1.component.spec.ts | 0 .../getting-started1/getting-started1.component.ts | 0 .../getting-started2.component.html | 0 .../getting-started2.component.scss | 0 .../getting-started2.component.spec.ts | 0 .../getting-started2/getting-started2.component.ts | 0 .../getting-started3.component.html | 0 .../getting-started3.component.scss | 0 .../getting-started3.component.spec.ts | 0 .../getting-started3/getting-started3.component.ts | 0 .../route-components/landing/landing.component.html | 0 .../route-components/landing/landing.component.scss | 0 .../landing/landing.component.spec.ts | 0 .../route-components/landing/landing.component.ts | 0 .../ministry-confirmation.component.html | 0 .../ministry-confirmation.component.scss | 0 .../ministry-confirmation.component.spec.ts | 0 .../ministry-confirmation.component.ts | 0 .../proof-of-guardianship.component.html | 0 .../proof-of-guardianship.component.scss | 0 .../proof-of-guardianship.component.spec.ts | 0 .../proof-of-guardianship.component.ts | 0 .../request-topic/request-topic.component.html | 0 .../request-topic/request-topic.component.scss | 0 .../request-topic/request-topic.component.spec.ts | 0 .../request-topic/request-topic.component.ts | 0 .../review-submit-complete.component.html | 0 .../review-submit-complete.component.scss | 0 .../review-submit-complete.component.spec.ts | 0 .../review-submit-complete.component.ts | 0 .../review-submit/review-submit.component.html | 0 .../review-submit/review-submit.component.scss | 0 .../review-submit/review-submit.component.spec.ts | 0 .../review-submit/review-submit.component.ts | 0 .../app/route-components/route-components.module.ts | 0 .../select-about/select-about.component.html | 0 .../select-about/select-about.component.scss | 0 .../select-about/select-about.component.spec.ts | 0 .../select-about/select-about.component.ts | 0 .../route-components/signin/signin.component.html | 0 .../route-components/signin/signin.component.scss | 0 .../signin/signin.component.spec.ts | 0 .../app/route-components/signin/signin.component.ts | 0 .../start-request/start-request.component.html | 0 .../start-request/start-request.component.scss | 0 .../start-request/start-request.component.spec.ts | 0 .../start-request/start-request.component.ts | 0 .../verify-your-identity.component.html | 0 .../verify-your-identity.component.scss | 0 .../verify-your-identity.component.spec.ts | 0 .../verify-your-identity.component.ts | 0 .../src}/app/services/app-config.service.spec.ts | 0 {src => web/src}/app/services/app-config.service.ts | 0 .../src}/app/services/captcha-data.service.spec.ts | 0 .../src}/app/services/captcha-data.service.ts | 0 {src => web/src}/app/services/data.d.ts | 0 {src => web/src}/app/services/data.json | 0 {src => web/src}/app/services/data.service.spec.ts | 0 {src => web/src}/app/services/data.service.ts | 0 {src => web/src}/app/services/keycloak-config.json | 0 .../src}/app/services/keycloak.service.spec.ts | 0 {src => web/src}/app/services/keycloak.service.ts | 0 {src => web/src}/app/services/services.module.ts | 0 .../src}/app/services/window-ref.service.spec.ts | 0 {src => web/src}/app/services/window-ref.service.ts | 0 {src => web/src}/app/styles/overrides.scss | 0 {src => web/src}/app/styles/variables.scss | 0 .../src}/app/transom-api-client.service.spec.ts | 0 {src => web/src}/app/transom-api-client.service.ts | 0 .../alert-info/alert-info.component.html | 0 .../alert-info/alert-info.component.scss | 0 .../alert-info/alert-info.component.spec.ts | 0 .../alert-info/alert-info.component.ts | 0 .../alert-success/alert-success.component.html | 0 .../alert-success/alert-success.component.scss | 0 .../alert-success/alert-success.component.spec.ts | 0 .../alert-success/alert-success.component.ts | 0 .../alert-warning/alert-warning.component.html | 0 .../alert-warning/alert-warning.component.scss | 0 .../alert-warning/alert-warning.component.spec.ts | 0 .../alert-warning/alert-warning.component.ts | 0 .../app/utils-components/base/base.component.html | 0 .../app/utils-components/base/base.component.scss | 0 .../utils-components/base/base.component.spec.ts | 0 .../app/utils-components/base/base.component.ts | 0 .../utils-components/captcha/captcha.component.html | 0 .../utils-components/captcha/captcha.component.scss | 0 .../captcha/captcha.component.spec.ts | 0 .../utils-components/captcha/captcha.component.ts | 0 .../foi-fileinput/foi-fileinput.component.html | 0 .../foi-fileinput/foi-fileinput.component.scss | 0 .../foi-fileinput/foi-fileinput.component.spec.ts | 0 .../foi-fileinput/foi-fileinput.component.ts | 0 .../foi-valid/foi-valid.component.html | 0 .../foi-valid/foi-valid.component.scss | 0 .../foi-valid/foi-valid.component.spec.ts | 0 .../foi-valid/foi-valid.component.ts | 0 .../static-contact-block.component.html | 0 .../static-contact-block.component.scss | 0 .../static-contact-block.component.spec.ts | 0 .../static-contact-block.component.ts | 0 .../app/utils-components/utils-components.module.ts | 0 {src => web/src}/assets/.gitkeep | 0 {src => web/src}/assets/fonts/MyriadWebPro.ttf | Bin .../src}/assets/images/bc_logo_transparent.png | Bin {src => web/src}/assets/images/gov3_bc_logo.png | Bin {src => web/src}/browserslist | 0 {src => web/src}/environments/environment.prod.ts | 0 {src => web/src}/environments/environment.ts | 0 {src => web/src}/favicon.ico | Bin {src => web/src}/index.html | 0 {src => web/src}/karma.conf.js | 0 {src => web/src}/main.ts | 0 {src => web/src}/polyfills.ts | 0 {src => web/src}/proxy.conf.json | 0 {src => web/src}/styles.scss | 0 {src => web/src}/test.ts | 0 {src => web/src}/tsconfig.app.json | 0 {src => web/src}/tsconfig.spec.json | 0 {src => web/src}/tslint.json | 0 {src => web/src}/typings.d.ts | 0 tsconfig.json => web/tsconfig.json | 0 tslint.json => web/tslint.json | 0 189 files changed, 3 insertions(+) rename angular.json => web/angular.json (100%) rename package-lock.json => web/package-lock.json (100%) rename package.json => web/package.json (100%) rename {src => web/src}/.prettierrc (100%) rename {src => web/src}/app/MockClasses.ts (100%) rename {src => web/src}/app/app-routing.module.ts (100%) rename {src => web/src}/app/app.component.html (100%) rename {src => web/src}/app/app.component.scss (100%) rename {src => web/src}/app/app.component.spec.ts (100%) rename {src => web/src}/app/app.component.ts (100%) rename {src => web/src}/app/app.module.ts (100%) rename {src => web/src}/app/core-header/core-header.component.html (100%) rename {src => web/src}/app/core-header/core-header.component.scss (100%) rename {src => web/src}/app/core-header/core-header.component.spec.ts (100%) rename {src => web/src}/app/core-header/core-header.component.ts (100%) rename {src => web/src}/app/foi-router.service.spec.ts (100%) rename {src => web/src}/app/foi-router.service.ts (100%) rename {src => web/src}/app/footer/footer.component.html (100%) rename {src => web/src}/app/footer/footer.component.scss (100%) rename {src => web/src}/app/footer/footer.component.spec.ts (100%) rename {src => web/src}/app/footer/footer.component.ts (100%) rename {src => web/src}/app/models/FoiRequest.ts (100%) rename {src => web/src}/app/models/FoiRoute.ts (100%) rename {src => web/src}/app/models/user.ts (100%) rename {src => web/src}/app/progress-bar/progress-bar.component.html (100%) rename {src => web/src}/app/progress-bar/progress-bar.component.scss (100%) rename {src => web/src}/app/progress-bar/progress-bar.component.spec.ts (100%) rename {src => web/src}/app/progress-bar/progress-bar.component.ts (100%) rename {src => web/src}/app/route-components/adoptive-parents/adoptive-parents.component.html (100%) rename {src => web/src}/app/route-components/adoptive-parents/adoptive-parents.component.scss (100%) rename {src => web/src}/app/route-components/adoptive-parents/adoptive-parents.component.spec.ts (100%) rename {src => web/src}/app/route-components/adoptive-parents/adoptive-parents.component.ts (100%) rename {src => web/src}/app/route-components/another-information/another-information.component.html (100%) rename {src => web/src}/app/route-components/another-information/another-information.component.scss (100%) rename {src => web/src}/app/route-components/another-information/another-information.component.spec.ts (100%) rename {src => web/src}/app/route-components/another-information/another-information.component.ts (100%) rename {src => web/src}/app/route-components/child-information/child-information.component.html (100%) rename {src => web/src}/app/route-components/child-information/child-information.component.scss (100%) rename {src => web/src}/app/route-components/child-information/child-information.component.spec.ts (100%) rename {src => web/src}/app/route-components/child-information/child-information.component.ts (100%) rename {src => web/src}/app/route-components/choose-identity/choose-identity.component.html (100%) rename {src => web/src}/app/route-components/choose-identity/choose-identity.component.scss (100%) rename {src => web/src}/app/route-components/choose-identity/choose-identity.component.spec.ts (100%) rename {src => web/src}/app/route-components/choose-identity/choose-identity.component.ts (100%) rename {src => web/src}/app/route-components/contact-info-options/contact-info-options.component.html (100%) rename {src => web/src}/app/route-components/contact-info-options/contact-info-options.component.scss (100%) rename {src => web/src}/app/route-components/contact-info-options/contact-info-options.component.spec.ts (100%) rename {src => web/src}/app/route-components/contact-info-options/contact-info-options.component.ts (100%) rename {src => web/src}/app/route-components/contact-info/contact-info.component.html (100%) rename {src => web/src}/app/route-components/contact-info/contact-info.component.scss (100%) rename {src => web/src}/app/route-components/contact-info/contact-info.component.spec.ts (100%) rename {src => web/src}/app/route-components/contact-info/contact-info.component.ts (100%) rename {src => web/src}/app/route-components/description-timeframe/description-timeframe.component.html (100%) rename {src => web/src}/app/route-components/description-timeframe/description-timeframe.component.scss (100%) rename {src => web/src}/app/route-components/description-timeframe/description-timeframe.component.spec.ts (100%) rename {src => web/src}/app/route-components/description-timeframe/description-timeframe.component.ts (100%) rename {src => web/src}/app/route-components/general-info/general-info.component.html (100%) rename {src => web/src}/app/route-components/general-info/general-info.component.scss (100%) rename {src => web/src}/app/route-components/general-info/general-info.component.ts (100%) rename {src => web/src}/app/route-components/general-select-ministry/general-select-ministry.component.html (100%) rename {src => web/src}/app/route-components/general-select-ministry/general-select-ministry.component.scss (100%) rename {src => web/src}/app/route-components/general-select-ministry/general-select-ministry.component.spec.ts (100%) rename {src => web/src}/app/route-components/general-select-ministry/general-select-ministry.component.ts (100%) rename {src => web/src}/app/route-components/getting-started1/getting-started1.component.html (100%) rename {src => web/src}/app/route-components/getting-started1/getting-started1.component.scss (100%) rename {src => web/src}/app/route-components/getting-started1/getting-started1.component.spec.ts (100%) rename {src => web/src}/app/route-components/getting-started1/getting-started1.component.ts (100%) rename {src => web/src}/app/route-components/getting-started2/getting-started2.component.html (100%) rename {src => web/src}/app/route-components/getting-started2/getting-started2.component.scss (100%) rename {src => web/src}/app/route-components/getting-started2/getting-started2.component.spec.ts (100%) rename {src => web/src}/app/route-components/getting-started2/getting-started2.component.ts (100%) rename {src => web/src}/app/route-components/getting-started3/getting-started3.component.html (100%) rename {src => web/src}/app/route-components/getting-started3/getting-started3.component.scss (100%) rename {src => web/src}/app/route-components/getting-started3/getting-started3.component.spec.ts (100%) rename {src => web/src}/app/route-components/getting-started3/getting-started3.component.ts (100%) rename {src => web/src}/app/route-components/landing/landing.component.html (100%) rename {src => web/src}/app/route-components/landing/landing.component.scss (100%) rename {src => web/src}/app/route-components/landing/landing.component.spec.ts (100%) rename {src => web/src}/app/route-components/landing/landing.component.ts (100%) rename {src => web/src}/app/route-components/ministry-confirmation/ministry-confirmation.component.html (100%) rename {src => web/src}/app/route-components/ministry-confirmation/ministry-confirmation.component.scss (100%) rename {src => web/src}/app/route-components/ministry-confirmation/ministry-confirmation.component.spec.ts (100%) rename {src => web/src}/app/route-components/ministry-confirmation/ministry-confirmation.component.ts (100%) rename {src => web/src}/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html (100%) rename {src => web/src}/app/route-components/proof-of-guardianship/proof-of-guardianship.component.scss (100%) rename {src => web/src}/app/route-components/proof-of-guardianship/proof-of-guardianship.component.spec.ts (100%) rename {src => web/src}/app/route-components/proof-of-guardianship/proof-of-guardianship.component.ts (100%) rename {src => web/src}/app/route-components/request-topic/request-topic.component.html (100%) rename {src => web/src}/app/route-components/request-topic/request-topic.component.scss (100%) rename {src => web/src}/app/route-components/request-topic/request-topic.component.spec.ts (100%) rename {src => web/src}/app/route-components/request-topic/request-topic.component.ts (100%) rename {src => web/src}/app/route-components/review-submit-complete/review-submit-complete.component.html (100%) rename {src => web/src}/app/route-components/review-submit-complete/review-submit-complete.component.scss (100%) rename {src => web/src}/app/route-components/review-submit-complete/review-submit-complete.component.spec.ts (100%) rename {src => web/src}/app/route-components/review-submit-complete/review-submit-complete.component.ts (100%) rename {src => web/src}/app/route-components/review-submit/review-submit.component.html (100%) rename {src => web/src}/app/route-components/review-submit/review-submit.component.scss (100%) rename {src => web/src}/app/route-components/review-submit/review-submit.component.spec.ts (100%) rename {src => web/src}/app/route-components/review-submit/review-submit.component.ts (100%) rename {src => web/src}/app/route-components/route-components.module.ts (100%) rename {src => web/src}/app/route-components/select-about/select-about.component.html (100%) rename {src => web/src}/app/route-components/select-about/select-about.component.scss (100%) rename {src => web/src}/app/route-components/select-about/select-about.component.spec.ts (100%) rename {src => web/src}/app/route-components/select-about/select-about.component.ts (100%) rename {src => web/src}/app/route-components/signin/signin.component.html (100%) rename {src => web/src}/app/route-components/signin/signin.component.scss (100%) rename {src => web/src}/app/route-components/signin/signin.component.spec.ts (100%) rename {src => web/src}/app/route-components/signin/signin.component.ts (100%) rename {src => web/src}/app/route-components/start-request/start-request.component.html (100%) rename {src => web/src}/app/route-components/start-request/start-request.component.scss (100%) rename {src => web/src}/app/route-components/start-request/start-request.component.spec.ts (100%) rename {src => web/src}/app/route-components/start-request/start-request.component.ts (100%) rename {src => web/src}/app/route-components/verify-your-identity/verify-your-identity.component.html (100%) rename {src => web/src}/app/route-components/verify-your-identity/verify-your-identity.component.scss (100%) rename {src => web/src}/app/route-components/verify-your-identity/verify-your-identity.component.spec.ts (100%) rename {src => web/src}/app/route-components/verify-your-identity/verify-your-identity.component.ts (100%) rename {src => web/src}/app/services/app-config.service.spec.ts (100%) rename {src => web/src}/app/services/app-config.service.ts (100%) rename {src => web/src}/app/services/captcha-data.service.spec.ts (100%) rename {src => web/src}/app/services/captcha-data.service.ts (100%) rename {src => web/src}/app/services/data.d.ts (100%) rename {src => web/src}/app/services/data.json (100%) rename {src => web/src}/app/services/data.service.spec.ts (100%) rename {src => web/src}/app/services/data.service.ts (100%) rename {src => web/src}/app/services/keycloak-config.json (100%) rename {src => web/src}/app/services/keycloak.service.spec.ts (100%) rename {src => web/src}/app/services/keycloak.service.ts (100%) rename {src => web/src}/app/services/services.module.ts (100%) rename {src => web/src}/app/services/window-ref.service.spec.ts (100%) rename {src => web/src}/app/services/window-ref.service.ts (100%) rename {src => web/src}/app/styles/overrides.scss (100%) rename {src => web/src}/app/styles/variables.scss (100%) rename {src => web/src}/app/transom-api-client.service.spec.ts (100%) rename {src => web/src}/app/transom-api-client.service.ts (100%) rename {src => web/src}/app/utils-components/alert-info/alert-info.component.html (100%) rename {src => web/src}/app/utils-components/alert-info/alert-info.component.scss (100%) rename {src => web/src}/app/utils-components/alert-info/alert-info.component.spec.ts (100%) rename {src => web/src}/app/utils-components/alert-info/alert-info.component.ts (100%) rename {src => web/src}/app/utils-components/alert-success/alert-success.component.html (100%) rename {src => web/src}/app/utils-components/alert-success/alert-success.component.scss (100%) rename {src => web/src}/app/utils-components/alert-success/alert-success.component.spec.ts (100%) rename {src => web/src}/app/utils-components/alert-success/alert-success.component.ts (100%) rename {src => web/src}/app/utils-components/alert-warning/alert-warning.component.html (100%) rename {src => web/src}/app/utils-components/alert-warning/alert-warning.component.scss (100%) rename {src => web/src}/app/utils-components/alert-warning/alert-warning.component.spec.ts (100%) rename {src => web/src}/app/utils-components/alert-warning/alert-warning.component.ts (100%) rename {src => web/src}/app/utils-components/base/base.component.html (100%) rename {src => web/src}/app/utils-components/base/base.component.scss (100%) rename {src => web/src}/app/utils-components/base/base.component.spec.ts (100%) rename {src => web/src}/app/utils-components/base/base.component.ts (100%) rename {src => web/src}/app/utils-components/captcha/captcha.component.html (100%) rename {src => web/src}/app/utils-components/captcha/captcha.component.scss (100%) rename {src => web/src}/app/utils-components/captcha/captcha.component.spec.ts (100%) rename {src => web/src}/app/utils-components/captcha/captcha.component.ts (100%) rename {src => web/src}/app/utils-components/foi-fileinput/foi-fileinput.component.html (100%) rename {src => web/src}/app/utils-components/foi-fileinput/foi-fileinput.component.scss (100%) rename {src => web/src}/app/utils-components/foi-fileinput/foi-fileinput.component.spec.ts (100%) rename {src => web/src}/app/utils-components/foi-fileinput/foi-fileinput.component.ts (100%) rename {src => web/src}/app/utils-components/foi-valid/foi-valid.component.html (100%) rename {src => web/src}/app/utils-components/foi-valid/foi-valid.component.scss (100%) rename {src => web/src}/app/utils-components/foi-valid/foi-valid.component.spec.ts (100%) rename {src => web/src}/app/utils-components/foi-valid/foi-valid.component.ts (100%) rename {src => web/src}/app/utils-components/static-contact-block/static-contact-block.component.html (100%) rename {src => web/src}/app/utils-components/static-contact-block/static-contact-block.component.scss (100%) rename {src => web/src}/app/utils-components/static-contact-block/static-contact-block.component.spec.ts (100%) rename {src => web/src}/app/utils-components/static-contact-block/static-contact-block.component.ts (100%) rename {src => web/src}/app/utils-components/utils-components.module.ts (100%) rename {src => web/src}/assets/.gitkeep (100%) rename {src => web/src}/assets/fonts/MyriadWebPro.ttf (100%) rename {src => web/src}/assets/images/bc_logo_transparent.png (100%) rename {src => web/src}/assets/images/gov3_bc_logo.png (100%) rename {src => web/src}/browserslist (100%) rename {src => web/src}/environments/environment.prod.ts (100%) rename {src => web/src}/environments/environment.ts (100%) rename {src => web/src}/favicon.ico (100%) rename {src => web/src}/index.html (100%) rename {src => web/src}/karma.conf.js (100%) rename {src => web/src}/main.ts (100%) rename {src => web/src}/polyfills.ts (100%) rename {src => web/src}/proxy.conf.json (100%) rename {src => web/src}/styles.scss (100%) rename {src => web/src}/test.ts (100%) rename {src => web/src}/tsconfig.app.json (100%) rename {src => web/src}/tsconfig.spec.json (100%) rename {src => web/src}/tslint.json (100%) rename {src => web/src}/typings.d.ts (100%) rename tsconfig.json => web/tsconfig.json (100%) rename tslint.json => web/tslint.json (100%) diff --git a/.gitignore b/.gitignore index b938bb81..aa17de32 100644 --- a/.gitignore +++ b/.gitignore @@ -40,5 +40,8 @@ testem.log # System Files .DS_Store Thumbs.db + +# SSL *.pem *.key +*.csr \ No newline at end of file diff --git a/angular.json b/web/angular.json similarity index 100% rename from angular.json rename to web/angular.json diff --git a/package-lock.json b/web/package-lock.json similarity index 100% rename from package-lock.json rename to web/package-lock.json diff --git a/package.json b/web/package.json similarity index 100% rename from package.json rename to web/package.json diff --git a/src/.prettierrc b/web/src/.prettierrc similarity index 100% rename from src/.prettierrc rename to web/src/.prettierrc diff --git a/src/app/MockClasses.ts b/web/src/app/MockClasses.ts similarity index 100% rename from src/app/MockClasses.ts rename to web/src/app/MockClasses.ts diff --git a/src/app/app-routing.module.ts b/web/src/app/app-routing.module.ts similarity index 100% rename from src/app/app-routing.module.ts rename to web/src/app/app-routing.module.ts diff --git a/src/app/app.component.html b/web/src/app/app.component.html similarity index 100% rename from src/app/app.component.html rename to web/src/app/app.component.html diff --git a/src/app/app.component.scss b/web/src/app/app.component.scss similarity index 100% rename from src/app/app.component.scss rename to web/src/app/app.component.scss diff --git a/src/app/app.component.spec.ts b/web/src/app/app.component.spec.ts similarity index 100% rename from src/app/app.component.spec.ts rename to web/src/app/app.component.spec.ts diff --git a/src/app/app.component.ts b/web/src/app/app.component.ts similarity index 100% rename from src/app/app.component.ts rename to web/src/app/app.component.ts diff --git a/src/app/app.module.ts b/web/src/app/app.module.ts similarity index 100% rename from src/app/app.module.ts rename to web/src/app/app.module.ts diff --git a/src/app/core-header/core-header.component.html b/web/src/app/core-header/core-header.component.html similarity index 100% rename from src/app/core-header/core-header.component.html rename to web/src/app/core-header/core-header.component.html diff --git a/src/app/core-header/core-header.component.scss b/web/src/app/core-header/core-header.component.scss similarity index 100% rename from src/app/core-header/core-header.component.scss rename to web/src/app/core-header/core-header.component.scss diff --git a/src/app/core-header/core-header.component.spec.ts b/web/src/app/core-header/core-header.component.spec.ts similarity index 100% rename from src/app/core-header/core-header.component.spec.ts rename to web/src/app/core-header/core-header.component.spec.ts diff --git a/src/app/core-header/core-header.component.ts b/web/src/app/core-header/core-header.component.ts similarity index 100% rename from src/app/core-header/core-header.component.ts rename to web/src/app/core-header/core-header.component.ts diff --git a/src/app/foi-router.service.spec.ts b/web/src/app/foi-router.service.spec.ts similarity index 100% rename from src/app/foi-router.service.spec.ts rename to web/src/app/foi-router.service.spec.ts diff --git a/src/app/foi-router.service.ts b/web/src/app/foi-router.service.ts similarity index 100% rename from src/app/foi-router.service.ts rename to web/src/app/foi-router.service.ts diff --git a/src/app/footer/footer.component.html b/web/src/app/footer/footer.component.html similarity index 100% rename from src/app/footer/footer.component.html rename to web/src/app/footer/footer.component.html diff --git a/src/app/footer/footer.component.scss b/web/src/app/footer/footer.component.scss similarity index 100% rename from src/app/footer/footer.component.scss rename to web/src/app/footer/footer.component.scss diff --git a/src/app/footer/footer.component.spec.ts b/web/src/app/footer/footer.component.spec.ts similarity index 100% rename from src/app/footer/footer.component.spec.ts rename to web/src/app/footer/footer.component.spec.ts diff --git a/src/app/footer/footer.component.ts b/web/src/app/footer/footer.component.ts similarity index 100% rename from src/app/footer/footer.component.ts rename to web/src/app/footer/footer.component.ts diff --git a/src/app/models/FoiRequest.ts b/web/src/app/models/FoiRequest.ts similarity index 100% rename from src/app/models/FoiRequest.ts rename to web/src/app/models/FoiRequest.ts diff --git a/src/app/models/FoiRoute.ts b/web/src/app/models/FoiRoute.ts similarity index 100% rename from src/app/models/FoiRoute.ts rename to web/src/app/models/FoiRoute.ts diff --git a/src/app/models/user.ts b/web/src/app/models/user.ts similarity index 100% rename from src/app/models/user.ts rename to web/src/app/models/user.ts diff --git a/src/app/progress-bar/progress-bar.component.html b/web/src/app/progress-bar/progress-bar.component.html similarity index 100% rename from src/app/progress-bar/progress-bar.component.html rename to web/src/app/progress-bar/progress-bar.component.html diff --git a/src/app/progress-bar/progress-bar.component.scss b/web/src/app/progress-bar/progress-bar.component.scss similarity index 100% rename from src/app/progress-bar/progress-bar.component.scss rename to web/src/app/progress-bar/progress-bar.component.scss diff --git a/src/app/progress-bar/progress-bar.component.spec.ts b/web/src/app/progress-bar/progress-bar.component.spec.ts similarity index 100% rename from src/app/progress-bar/progress-bar.component.spec.ts rename to web/src/app/progress-bar/progress-bar.component.spec.ts diff --git a/src/app/progress-bar/progress-bar.component.ts b/web/src/app/progress-bar/progress-bar.component.ts similarity index 100% rename from src/app/progress-bar/progress-bar.component.ts rename to web/src/app/progress-bar/progress-bar.component.ts diff --git a/src/app/route-components/adoptive-parents/adoptive-parents.component.html b/web/src/app/route-components/adoptive-parents/adoptive-parents.component.html similarity index 100% rename from src/app/route-components/adoptive-parents/adoptive-parents.component.html rename to web/src/app/route-components/adoptive-parents/adoptive-parents.component.html diff --git a/src/app/route-components/adoptive-parents/adoptive-parents.component.scss b/web/src/app/route-components/adoptive-parents/adoptive-parents.component.scss similarity index 100% rename from src/app/route-components/adoptive-parents/adoptive-parents.component.scss rename to web/src/app/route-components/adoptive-parents/adoptive-parents.component.scss diff --git a/src/app/route-components/adoptive-parents/adoptive-parents.component.spec.ts b/web/src/app/route-components/adoptive-parents/adoptive-parents.component.spec.ts similarity index 100% rename from src/app/route-components/adoptive-parents/adoptive-parents.component.spec.ts rename to web/src/app/route-components/adoptive-parents/adoptive-parents.component.spec.ts diff --git a/src/app/route-components/adoptive-parents/adoptive-parents.component.ts b/web/src/app/route-components/adoptive-parents/adoptive-parents.component.ts similarity index 100% rename from src/app/route-components/adoptive-parents/adoptive-parents.component.ts rename to web/src/app/route-components/adoptive-parents/adoptive-parents.component.ts diff --git a/src/app/route-components/another-information/another-information.component.html b/web/src/app/route-components/another-information/another-information.component.html similarity index 100% rename from src/app/route-components/another-information/another-information.component.html rename to web/src/app/route-components/another-information/another-information.component.html diff --git a/src/app/route-components/another-information/another-information.component.scss b/web/src/app/route-components/another-information/another-information.component.scss similarity index 100% rename from src/app/route-components/another-information/another-information.component.scss rename to web/src/app/route-components/another-information/another-information.component.scss diff --git a/src/app/route-components/another-information/another-information.component.spec.ts b/web/src/app/route-components/another-information/another-information.component.spec.ts similarity index 100% rename from src/app/route-components/another-information/another-information.component.spec.ts rename to web/src/app/route-components/another-information/another-information.component.spec.ts diff --git a/src/app/route-components/another-information/another-information.component.ts b/web/src/app/route-components/another-information/another-information.component.ts similarity index 100% rename from src/app/route-components/another-information/another-information.component.ts rename to web/src/app/route-components/another-information/another-information.component.ts diff --git a/src/app/route-components/child-information/child-information.component.html b/web/src/app/route-components/child-information/child-information.component.html similarity index 100% rename from src/app/route-components/child-information/child-information.component.html rename to web/src/app/route-components/child-information/child-information.component.html diff --git a/src/app/route-components/child-information/child-information.component.scss b/web/src/app/route-components/child-information/child-information.component.scss similarity index 100% rename from src/app/route-components/child-information/child-information.component.scss rename to web/src/app/route-components/child-information/child-information.component.scss diff --git a/src/app/route-components/child-information/child-information.component.spec.ts b/web/src/app/route-components/child-information/child-information.component.spec.ts similarity index 100% rename from src/app/route-components/child-information/child-information.component.spec.ts rename to web/src/app/route-components/child-information/child-information.component.spec.ts diff --git a/src/app/route-components/child-information/child-information.component.ts b/web/src/app/route-components/child-information/child-information.component.ts similarity index 100% rename from src/app/route-components/child-information/child-information.component.ts rename to web/src/app/route-components/child-information/child-information.component.ts diff --git a/src/app/route-components/choose-identity/choose-identity.component.html b/web/src/app/route-components/choose-identity/choose-identity.component.html similarity index 100% rename from src/app/route-components/choose-identity/choose-identity.component.html rename to web/src/app/route-components/choose-identity/choose-identity.component.html diff --git a/src/app/route-components/choose-identity/choose-identity.component.scss b/web/src/app/route-components/choose-identity/choose-identity.component.scss similarity index 100% rename from src/app/route-components/choose-identity/choose-identity.component.scss rename to web/src/app/route-components/choose-identity/choose-identity.component.scss diff --git a/src/app/route-components/choose-identity/choose-identity.component.spec.ts b/web/src/app/route-components/choose-identity/choose-identity.component.spec.ts similarity index 100% rename from src/app/route-components/choose-identity/choose-identity.component.spec.ts rename to web/src/app/route-components/choose-identity/choose-identity.component.spec.ts diff --git a/src/app/route-components/choose-identity/choose-identity.component.ts b/web/src/app/route-components/choose-identity/choose-identity.component.ts similarity index 100% rename from src/app/route-components/choose-identity/choose-identity.component.ts rename to web/src/app/route-components/choose-identity/choose-identity.component.ts diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.html b/web/src/app/route-components/contact-info-options/contact-info-options.component.html similarity index 100% rename from src/app/route-components/contact-info-options/contact-info-options.component.html rename to web/src/app/route-components/contact-info-options/contact-info-options.component.html diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.scss b/web/src/app/route-components/contact-info-options/contact-info-options.component.scss similarity index 100% rename from src/app/route-components/contact-info-options/contact-info-options.component.scss rename to web/src/app/route-components/contact-info-options/contact-info-options.component.scss diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.spec.ts b/web/src/app/route-components/contact-info-options/contact-info-options.component.spec.ts similarity index 100% rename from src/app/route-components/contact-info-options/contact-info-options.component.spec.ts rename to web/src/app/route-components/contact-info-options/contact-info-options.component.spec.ts diff --git a/src/app/route-components/contact-info-options/contact-info-options.component.ts b/web/src/app/route-components/contact-info-options/contact-info-options.component.ts similarity index 100% rename from src/app/route-components/contact-info-options/contact-info-options.component.ts rename to web/src/app/route-components/contact-info-options/contact-info-options.component.ts diff --git a/src/app/route-components/contact-info/contact-info.component.html b/web/src/app/route-components/contact-info/contact-info.component.html similarity index 100% rename from src/app/route-components/contact-info/contact-info.component.html rename to web/src/app/route-components/contact-info/contact-info.component.html diff --git a/src/app/route-components/contact-info/contact-info.component.scss b/web/src/app/route-components/contact-info/contact-info.component.scss similarity index 100% rename from src/app/route-components/contact-info/contact-info.component.scss rename to web/src/app/route-components/contact-info/contact-info.component.scss diff --git a/src/app/route-components/contact-info/contact-info.component.spec.ts b/web/src/app/route-components/contact-info/contact-info.component.spec.ts similarity index 100% rename from src/app/route-components/contact-info/contact-info.component.spec.ts rename to web/src/app/route-components/contact-info/contact-info.component.spec.ts diff --git a/src/app/route-components/contact-info/contact-info.component.ts b/web/src/app/route-components/contact-info/contact-info.component.ts similarity index 100% rename from src/app/route-components/contact-info/contact-info.component.ts rename to web/src/app/route-components/contact-info/contact-info.component.ts diff --git a/src/app/route-components/description-timeframe/description-timeframe.component.html b/web/src/app/route-components/description-timeframe/description-timeframe.component.html similarity index 100% rename from src/app/route-components/description-timeframe/description-timeframe.component.html rename to web/src/app/route-components/description-timeframe/description-timeframe.component.html diff --git a/src/app/route-components/description-timeframe/description-timeframe.component.scss b/web/src/app/route-components/description-timeframe/description-timeframe.component.scss similarity index 100% rename from src/app/route-components/description-timeframe/description-timeframe.component.scss rename to web/src/app/route-components/description-timeframe/description-timeframe.component.scss diff --git a/src/app/route-components/description-timeframe/description-timeframe.component.spec.ts b/web/src/app/route-components/description-timeframe/description-timeframe.component.spec.ts similarity index 100% rename from src/app/route-components/description-timeframe/description-timeframe.component.spec.ts rename to web/src/app/route-components/description-timeframe/description-timeframe.component.spec.ts diff --git a/src/app/route-components/description-timeframe/description-timeframe.component.ts b/web/src/app/route-components/description-timeframe/description-timeframe.component.ts similarity index 100% rename from src/app/route-components/description-timeframe/description-timeframe.component.ts rename to web/src/app/route-components/description-timeframe/description-timeframe.component.ts diff --git a/src/app/route-components/general-info/general-info.component.html b/web/src/app/route-components/general-info/general-info.component.html similarity index 100% rename from src/app/route-components/general-info/general-info.component.html rename to web/src/app/route-components/general-info/general-info.component.html diff --git a/src/app/route-components/general-info/general-info.component.scss b/web/src/app/route-components/general-info/general-info.component.scss similarity index 100% rename from src/app/route-components/general-info/general-info.component.scss rename to web/src/app/route-components/general-info/general-info.component.scss diff --git a/src/app/route-components/general-info/general-info.component.ts b/web/src/app/route-components/general-info/general-info.component.ts similarity index 100% rename from src/app/route-components/general-info/general-info.component.ts rename to web/src/app/route-components/general-info/general-info.component.ts diff --git a/src/app/route-components/general-select-ministry/general-select-ministry.component.html b/web/src/app/route-components/general-select-ministry/general-select-ministry.component.html similarity index 100% rename from src/app/route-components/general-select-ministry/general-select-ministry.component.html rename to web/src/app/route-components/general-select-ministry/general-select-ministry.component.html diff --git a/src/app/route-components/general-select-ministry/general-select-ministry.component.scss b/web/src/app/route-components/general-select-ministry/general-select-ministry.component.scss similarity index 100% rename from src/app/route-components/general-select-ministry/general-select-ministry.component.scss rename to web/src/app/route-components/general-select-ministry/general-select-ministry.component.scss diff --git a/src/app/route-components/general-select-ministry/general-select-ministry.component.spec.ts b/web/src/app/route-components/general-select-ministry/general-select-ministry.component.spec.ts similarity index 100% rename from src/app/route-components/general-select-ministry/general-select-ministry.component.spec.ts rename to web/src/app/route-components/general-select-ministry/general-select-ministry.component.spec.ts diff --git a/src/app/route-components/general-select-ministry/general-select-ministry.component.ts b/web/src/app/route-components/general-select-ministry/general-select-ministry.component.ts similarity index 100% rename from src/app/route-components/general-select-ministry/general-select-ministry.component.ts rename to web/src/app/route-components/general-select-ministry/general-select-ministry.component.ts diff --git a/src/app/route-components/getting-started1/getting-started1.component.html b/web/src/app/route-components/getting-started1/getting-started1.component.html similarity index 100% rename from src/app/route-components/getting-started1/getting-started1.component.html rename to web/src/app/route-components/getting-started1/getting-started1.component.html diff --git a/src/app/route-components/getting-started1/getting-started1.component.scss b/web/src/app/route-components/getting-started1/getting-started1.component.scss similarity index 100% rename from src/app/route-components/getting-started1/getting-started1.component.scss rename to web/src/app/route-components/getting-started1/getting-started1.component.scss diff --git a/src/app/route-components/getting-started1/getting-started1.component.spec.ts b/web/src/app/route-components/getting-started1/getting-started1.component.spec.ts similarity index 100% rename from src/app/route-components/getting-started1/getting-started1.component.spec.ts rename to web/src/app/route-components/getting-started1/getting-started1.component.spec.ts diff --git a/src/app/route-components/getting-started1/getting-started1.component.ts b/web/src/app/route-components/getting-started1/getting-started1.component.ts similarity index 100% rename from src/app/route-components/getting-started1/getting-started1.component.ts rename to web/src/app/route-components/getting-started1/getting-started1.component.ts diff --git a/src/app/route-components/getting-started2/getting-started2.component.html b/web/src/app/route-components/getting-started2/getting-started2.component.html similarity index 100% rename from src/app/route-components/getting-started2/getting-started2.component.html rename to web/src/app/route-components/getting-started2/getting-started2.component.html diff --git a/src/app/route-components/getting-started2/getting-started2.component.scss b/web/src/app/route-components/getting-started2/getting-started2.component.scss similarity index 100% rename from src/app/route-components/getting-started2/getting-started2.component.scss rename to web/src/app/route-components/getting-started2/getting-started2.component.scss diff --git a/src/app/route-components/getting-started2/getting-started2.component.spec.ts b/web/src/app/route-components/getting-started2/getting-started2.component.spec.ts similarity index 100% rename from src/app/route-components/getting-started2/getting-started2.component.spec.ts rename to web/src/app/route-components/getting-started2/getting-started2.component.spec.ts diff --git a/src/app/route-components/getting-started2/getting-started2.component.ts b/web/src/app/route-components/getting-started2/getting-started2.component.ts similarity index 100% rename from src/app/route-components/getting-started2/getting-started2.component.ts rename to web/src/app/route-components/getting-started2/getting-started2.component.ts diff --git a/src/app/route-components/getting-started3/getting-started3.component.html b/web/src/app/route-components/getting-started3/getting-started3.component.html similarity index 100% rename from src/app/route-components/getting-started3/getting-started3.component.html rename to web/src/app/route-components/getting-started3/getting-started3.component.html diff --git a/src/app/route-components/getting-started3/getting-started3.component.scss b/web/src/app/route-components/getting-started3/getting-started3.component.scss similarity index 100% rename from src/app/route-components/getting-started3/getting-started3.component.scss rename to web/src/app/route-components/getting-started3/getting-started3.component.scss diff --git a/src/app/route-components/getting-started3/getting-started3.component.spec.ts b/web/src/app/route-components/getting-started3/getting-started3.component.spec.ts similarity index 100% rename from src/app/route-components/getting-started3/getting-started3.component.spec.ts rename to web/src/app/route-components/getting-started3/getting-started3.component.spec.ts diff --git a/src/app/route-components/getting-started3/getting-started3.component.ts b/web/src/app/route-components/getting-started3/getting-started3.component.ts similarity index 100% rename from src/app/route-components/getting-started3/getting-started3.component.ts rename to web/src/app/route-components/getting-started3/getting-started3.component.ts diff --git a/src/app/route-components/landing/landing.component.html b/web/src/app/route-components/landing/landing.component.html similarity index 100% rename from src/app/route-components/landing/landing.component.html rename to web/src/app/route-components/landing/landing.component.html diff --git a/src/app/route-components/landing/landing.component.scss b/web/src/app/route-components/landing/landing.component.scss similarity index 100% rename from src/app/route-components/landing/landing.component.scss rename to web/src/app/route-components/landing/landing.component.scss diff --git a/src/app/route-components/landing/landing.component.spec.ts b/web/src/app/route-components/landing/landing.component.spec.ts similarity index 100% rename from src/app/route-components/landing/landing.component.spec.ts rename to web/src/app/route-components/landing/landing.component.spec.ts diff --git a/src/app/route-components/landing/landing.component.ts b/web/src/app/route-components/landing/landing.component.ts similarity index 100% rename from src/app/route-components/landing/landing.component.ts rename to web/src/app/route-components/landing/landing.component.ts diff --git a/src/app/route-components/ministry-confirmation/ministry-confirmation.component.html b/web/src/app/route-components/ministry-confirmation/ministry-confirmation.component.html similarity index 100% rename from src/app/route-components/ministry-confirmation/ministry-confirmation.component.html rename to web/src/app/route-components/ministry-confirmation/ministry-confirmation.component.html diff --git a/src/app/route-components/ministry-confirmation/ministry-confirmation.component.scss b/web/src/app/route-components/ministry-confirmation/ministry-confirmation.component.scss similarity index 100% rename from src/app/route-components/ministry-confirmation/ministry-confirmation.component.scss rename to web/src/app/route-components/ministry-confirmation/ministry-confirmation.component.scss diff --git a/src/app/route-components/ministry-confirmation/ministry-confirmation.component.spec.ts b/web/src/app/route-components/ministry-confirmation/ministry-confirmation.component.spec.ts similarity index 100% rename from src/app/route-components/ministry-confirmation/ministry-confirmation.component.spec.ts rename to web/src/app/route-components/ministry-confirmation/ministry-confirmation.component.spec.ts diff --git a/src/app/route-components/ministry-confirmation/ministry-confirmation.component.ts b/web/src/app/route-components/ministry-confirmation/ministry-confirmation.component.ts similarity index 100% rename from src/app/route-components/ministry-confirmation/ministry-confirmation.component.ts rename to web/src/app/route-components/ministry-confirmation/ministry-confirmation.component.ts diff --git a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html b/web/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html similarity index 100% rename from src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html rename to web/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.html diff --git a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.scss b/web/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.scss similarity index 100% rename from src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.scss rename to web/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.scss diff --git a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.spec.ts b/web/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.spec.ts similarity index 100% rename from src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.spec.ts rename to web/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.spec.ts diff --git a/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.ts b/web/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.ts similarity index 100% rename from src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.ts rename to web/src/app/route-components/proof-of-guardianship/proof-of-guardianship.component.ts diff --git a/src/app/route-components/request-topic/request-topic.component.html b/web/src/app/route-components/request-topic/request-topic.component.html similarity index 100% rename from src/app/route-components/request-topic/request-topic.component.html rename to web/src/app/route-components/request-topic/request-topic.component.html diff --git a/src/app/route-components/request-topic/request-topic.component.scss b/web/src/app/route-components/request-topic/request-topic.component.scss similarity index 100% rename from src/app/route-components/request-topic/request-topic.component.scss rename to web/src/app/route-components/request-topic/request-topic.component.scss diff --git a/src/app/route-components/request-topic/request-topic.component.spec.ts b/web/src/app/route-components/request-topic/request-topic.component.spec.ts similarity index 100% rename from src/app/route-components/request-topic/request-topic.component.spec.ts rename to web/src/app/route-components/request-topic/request-topic.component.spec.ts diff --git a/src/app/route-components/request-topic/request-topic.component.ts b/web/src/app/route-components/request-topic/request-topic.component.ts similarity index 100% rename from src/app/route-components/request-topic/request-topic.component.ts rename to web/src/app/route-components/request-topic/request-topic.component.ts diff --git a/src/app/route-components/review-submit-complete/review-submit-complete.component.html b/web/src/app/route-components/review-submit-complete/review-submit-complete.component.html similarity index 100% rename from src/app/route-components/review-submit-complete/review-submit-complete.component.html rename to web/src/app/route-components/review-submit-complete/review-submit-complete.component.html diff --git a/src/app/route-components/review-submit-complete/review-submit-complete.component.scss b/web/src/app/route-components/review-submit-complete/review-submit-complete.component.scss similarity index 100% rename from src/app/route-components/review-submit-complete/review-submit-complete.component.scss rename to web/src/app/route-components/review-submit-complete/review-submit-complete.component.scss diff --git a/src/app/route-components/review-submit-complete/review-submit-complete.component.spec.ts b/web/src/app/route-components/review-submit-complete/review-submit-complete.component.spec.ts similarity index 100% rename from src/app/route-components/review-submit-complete/review-submit-complete.component.spec.ts rename to web/src/app/route-components/review-submit-complete/review-submit-complete.component.spec.ts diff --git a/src/app/route-components/review-submit-complete/review-submit-complete.component.ts b/web/src/app/route-components/review-submit-complete/review-submit-complete.component.ts similarity index 100% rename from src/app/route-components/review-submit-complete/review-submit-complete.component.ts rename to web/src/app/route-components/review-submit-complete/review-submit-complete.component.ts diff --git a/src/app/route-components/review-submit/review-submit.component.html b/web/src/app/route-components/review-submit/review-submit.component.html similarity index 100% rename from src/app/route-components/review-submit/review-submit.component.html rename to web/src/app/route-components/review-submit/review-submit.component.html diff --git a/src/app/route-components/review-submit/review-submit.component.scss b/web/src/app/route-components/review-submit/review-submit.component.scss similarity index 100% rename from src/app/route-components/review-submit/review-submit.component.scss rename to web/src/app/route-components/review-submit/review-submit.component.scss diff --git a/src/app/route-components/review-submit/review-submit.component.spec.ts b/web/src/app/route-components/review-submit/review-submit.component.spec.ts similarity index 100% rename from src/app/route-components/review-submit/review-submit.component.spec.ts rename to web/src/app/route-components/review-submit/review-submit.component.spec.ts diff --git a/src/app/route-components/review-submit/review-submit.component.ts b/web/src/app/route-components/review-submit/review-submit.component.ts similarity index 100% rename from src/app/route-components/review-submit/review-submit.component.ts rename to web/src/app/route-components/review-submit/review-submit.component.ts diff --git a/src/app/route-components/route-components.module.ts b/web/src/app/route-components/route-components.module.ts similarity index 100% rename from src/app/route-components/route-components.module.ts rename to web/src/app/route-components/route-components.module.ts diff --git a/src/app/route-components/select-about/select-about.component.html b/web/src/app/route-components/select-about/select-about.component.html similarity index 100% rename from src/app/route-components/select-about/select-about.component.html rename to web/src/app/route-components/select-about/select-about.component.html diff --git a/src/app/route-components/select-about/select-about.component.scss b/web/src/app/route-components/select-about/select-about.component.scss similarity index 100% rename from src/app/route-components/select-about/select-about.component.scss rename to web/src/app/route-components/select-about/select-about.component.scss diff --git a/src/app/route-components/select-about/select-about.component.spec.ts b/web/src/app/route-components/select-about/select-about.component.spec.ts similarity index 100% rename from src/app/route-components/select-about/select-about.component.spec.ts rename to web/src/app/route-components/select-about/select-about.component.spec.ts diff --git a/src/app/route-components/select-about/select-about.component.ts b/web/src/app/route-components/select-about/select-about.component.ts similarity index 100% rename from src/app/route-components/select-about/select-about.component.ts rename to web/src/app/route-components/select-about/select-about.component.ts diff --git a/src/app/route-components/signin/signin.component.html b/web/src/app/route-components/signin/signin.component.html similarity index 100% rename from src/app/route-components/signin/signin.component.html rename to web/src/app/route-components/signin/signin.component.html diff --git a/src/app/route-components/signin/signin.component.scss b/web/src/app/route-components/signin/signin.component.scss similarity index 100% rename from src/app/route-components/signin/signin.component.scss rename to web/src/app/route-components/signin/signin.component.scss diff --git a/src/app/route-components/signin/signin.component.spec.ts b/web/src/app/route-components/signin/signin.component.spec.ts similarity index 100% rename from src/app/route-components/signin/signin.component.spec.ts rename to web/src/app/route-components/signin/signin.component.spec.ts diff --git a/src/app/route-components/signin/signin.component.ts b/web/src/app/route-components/signin/signin.component.ts similarity index 100% rename from src/app/route-components/signin/signin.component.ts rename to web/src/app/route-components/signin/signin.component.ts diff --git a/src/app/route-components/start-request/start-request.component.html b/web/src/app/route-components/start-request/start-request.component.html similarity index 100% rename from src/app/route-components/start-request/start-request.component.html rename to web/src/app/route-components/start-request/start-request.component.html diff --git a/src/app/route-components/start-request/start-request.component.scss b/web/src/app/route-components/start-request/start-request.component.scss similarity index 100% rename from src/app/route-components/start-request/start-request.component.scss rename to web/src/app/route-components/start-request/start-request.component.scss diff --git a/src/app/route-components/start-request/start-request.component.spec.ts b/web/src/app/route-components/start-request/start-request.component.spec.ts similarity index 100% rename from src/app/route-components/start-request/start-request.component.spec.ts rename to web/src/app/route-components/start-request/start-request.component.spec.ts diff --git a/src/app/route-components/start-request/start-request.component.ts b/web/src/app/route-components/start-request/start-request.component.ts similarity index 100% rename from src/app/route-components/start-request/start-request.component.ts rename to web/src/app/route-components/start-request/start-request.component.ts diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.html b/web/src/app/route-components/verify-your-identity/verify-your-identity.component.html similarity index 100% rename from src/app/route-components/verify-your-identity/verify-your-identity.component.html rename to web/src/app/route-components/verify-your-identity/verify-your-identity.component.html diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.scss b/web/src/app/route-components/verify-your-identity/verify-your-identity.component.scss similarity index 100% rename from src/app/route-components/verify-your-identity/verify-your-identity.component.scss rename to web/src/app/route-components/verify-your-identity/verify-your-identity.component.scss diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.spec.ts b/web/src/app/route-components/verify-your-identity/verify-your-identity.component.spec.ts similarity index 100% rename from src/app/route-components/verify-your-identity/verify-your-identity.component.spec.ts rename to web/src/app/route-components/verify-your-identity/verify-your-identity.component.spec.ts diff --git a/src/app/route-components/verify-your-identity/verify-your-identity.component.ts b/web/src/app/route-components/verify-your-identity/verify-your-identity.component.ts similarity index 100% rename from src/app/route-components/verify-your-identity/verify-your-identity.component.ts rename to web/src/app/route-components/verify-your-identity/verify-your-identity.component.ts diff --git a/src/app/services/app-config.service.spec.ts b/web/src/app/services/app-config.service.spec.ts similarity index 100% rename from src/app/services/app-config.service.spec.ts rename to web/src/app/services/app-config.service.spec.ts diff --git a/src/app/services/app-config.service.ts b/web/src/app/services/app-config.service.ts similarity index 100% rename from src/app/services/app-config.service.ts rename to web/src/app/services/app-config.service.ts diff --git a/src/app/services/captcha-data.service.spec.ts b/web/src/app/services/captcha-data.service.spec.ts similarity index 100% rename from src/app/services/captcha-data.service.spec.ts rename to web/src/app/services/captcha-data.service.spec.ts diff --git a/src/app/services/captcha-data.service.ts b/web/src/app/services/captcha-data.service.ts similarity index 100% rename from src/app/services/captcha-data.service.ts rename to web/src/app/services/captcha-data.service.ts diff --git a/src/app/services/data.d.ts b/web/src/app/services/data.d.ts similarity index 100% rename from src/app/services/data.d.ts rename to web/src/app/services/data.d.ts diff --git a/src/app/services/data.json b/web/src/app/services/data.json similarity index 100% rename from src/app/services/data.json rename to web/src/app/services/data.json diff --git a/src/app/services/data.service.spec.ts b/web/src/app/services/data.service.spec.ts similarity index 100% rename from src/app/services/data.service.spec.ts rename to web/src/app/services/data.service.spec.ts diff --git a/src/app/services/data.service.ts b/web/src/app/services/data.service.ts similarity index 100% rename from src/app/services/data.service.ts rename to web/src/app/services/data.service.ts diff --git a/src/app/services/keycloak-config.json b/web/src/app/services/keycloak-config.json similarity index 100% rename from src/app/services/keycloak-config.json rename to web/src/app/services/keycloak-config.json diff --git a/src/app/services/keycloak.service.spec.ts b/web/src/app/services/keycloak.service.spec.ts similarity index 100% rename from src/app/services/keycloak.service.spec.ts rename to web/src/app/services/keycloak.service.spec.ts diff --git a/src/app/services/keycloak.service.ts b/web/src/app/services/keycloak.service.ts similarity index 100% rename from src/app/services/keycloak.service.ts rename to web/src/app/services/keycloak.service.ts diff --git a/src/app/services/services.module.ts b/web/src/app/services/services.module.ts similarity index 100% rename from src/app/services/services.module.ts rename to web/src/app/services/services.module.ts diff --git a/src/app/services/window-ref.service.spec.ts b/web/src/app/services/window-ref.service.spec.ts similarity index 100% rename from src/app/services/window-ref.service.spec.ts rename to web/src/app/services/window-ref.service.spec.ts diff --git a/src/app/services/window-ref.service.ts b/web/src/app/services/window-ref.service.ts similarity index 100% rename from src/app/services/window-ref.service.ts rename to web/src/app/services/window-ref.service.ts diff --git a/src/app/styles/overrides.scss b/web/src/app/styles/overrides.scss similarity index 100% rename from src/app/styles/overrides.scss rename to web/src/app/styles/overrides.scss diff --git a/src/app/styles/variables.scss b/web/src/app/styles/variables.scss similarity index 100% rename from src/app/styles/variables.scss rename to web/src/app/styles/variables.scss diff --git a/src/app/transom-api-client.service.spec.ts b/web/src/app/transom-api-client.service.spec.ts similarity index 100% rename from src/app/transom-api-client.service.spec.ts rename to web/src/app/transom-api-client.service.spec.ts diff --git a/src/app/transom-api-client.service.ts b/web/src/app/transom-api-client.service.ts similarity index 100% rename from src/app/transom-api-client.service.ts rename to web/src/app/transom-api-client.service.ts diff --git a/src/app/utils-components/alert-info/alert-info.component.html b/web/src/app/utils-components/alert-info/alert-info.component.html similarity index 100% rename from src/app/utils-components/alert-info/alert-info.component.html rename to web/src/app/utils-components/alert-info/alert-info.component.html diff --git a/src/app/utils-components/alert-info/alert-info.component.scss b/web/src/app/utils-components/alert-info/alert-info.component.scss similarity index 100% rename from src/app/utils-components/alert-info/alert-info.component.scss rename to web/src/app/utils-components/alert-info/alert-info.component.scss diff --git a/src/app/utils-components/alert-info/alert-info.component.spec.ts b/web/src/app/utils-components/alert-info/alert-info.component.spec.ts similarity index 100% rename from src/app/utils-components/alert-info/alert-info.component.spec.ts rename to web/src/app/utils-components/alert-info/alert-info.component.spec.ts diff --git a/src/app/utils-components/alert-info/alert-info.component.ts b/web/src/app/utils-components/alert-info/alert-info.component.ts similarity index 100% rename from src/app/utils-components/alert-info/alert-info.component.ts rename to web/src/app/utils-components/alert-info/alert-info.component.ts diff --git a/src/app/utils-components/alert-success/alert-success.component.html b/web/src/app/utils-components/alert-success/alert-success.component.html similarity index 100% rename from src/app/utils-components/alert-success/alert-success.component.html rename to web/src/app/utils-components/alert-success/alert-success.component.html diff --git a/src/app/utils-components/alert-success/alert-success.component.scss b/web/src/app/utils-components/alert-success/alert-success.component.scss similarity index 100% rename from src/app/utils-components/alert-success/alert-success.component.scss rename to web/src/app/utils-components/alert-success/alert-success.component.scss diff --git a/src/app/utils-components/alert-success/alert-success.component.spec.ts b/web/src/app/utils-components/alert-success/alert-success.component.spec.ts similarity index 100% rename from src/app/utils-components/alert-success/alert-success.component.spec.ts rename to web/src/app/utils-components/alert-success/alert-success.component.spec.ts diff --git a/src/app/utils-components/alert-success/alert-success.component.ts b/web/src/app/utils-components/alert-success/alert-success.component.ts similarity index 100% rename from src/app/utils-components/alert-success/alert-success.component.ts rename to web/src/app/utils-components/alert-success/alert-success.component.ts diff --git a/src/app/utils-components/alert-warning/alert-warning.component.html b/web/src/app/utils-components/alert-warning/alert-warning.component.html similarity index 100% rename from src/app/utils-components/alert-warning/alert-warning.component.html rename to web/src/app/utils-components/alert-warning/alert-warning.component.html diff --git a/src/app/utils-components/alert-warning/alert-warning.component.scss b/web/src/app/utils-components/alert-warning/alert-warning.component.scss similarity index 100% rename from src/app/utils-components/alert-warning/alert-warning.component.scss rename to web/src/app/utils-components/alert-warning/alert-warning.component.scss diff --git a/src/app/utils-components/alert-warning/alert-warning.component.spec.ts b/web/src/app/utils-components/alert-warning/alert-warning.component.spec.ts similarity index 100% rename from src/app/utils-components/alert-warning/alert-warning.component.spec.ts rename to web/src/app/utils-components/alert-warning/alert-warning.component.spec.ts diff --git a/src/app/utils-components/alert-warning/alert-warning.component.ts b/web/src/app/utils-components/alert-warning/alert-warning.component.ts similarity index 100% rename from src/app/utils-components/alert-warning/alert-warning.component.ts rename to web/src/app/utils-components/alert-warning/alert-warning.component.ts diff --git a/src/app/utils-components/base/base.component.html b/web/src/app/utils-components/base/base.component.html similarity index 100% rename from src/app/utils-components/base/base.component.html rename to web/src/app/utils-components/base/base.component.html diff --git a/src/app/utils-components/base/base.component.scss b/web/src/app/utils-components/base/base.component.scss similarity index 100% rename from src/app/utils-components/base/base.component.scss rename to web/src/app/utils-components/base/base.component.scss diff --git a/src/app/utils-components/base/base.component.spec.ts b/web/src/app/utils-components/base/base.component.spec.ts similarity index 100% rename from src/app/utils-components/base/base.component.spec.ts rename to web/src/app/utils-components/base/base.component.spec.ts diff --git a/src/app/utils-components/base/base.component.ts b/web/src/app/utils-components/base/base.component.ts similarity index 100% rename from src/app/utils-components/base/base.component.ts rename to web/src/app/utils-components/base/base.component.ts diff --git a/src/app/utils-components/captcha/captcha.component.html b/web/src/app/utils-components/captcha/captcha.component.html similarity index 100% rename from src/app/utils-components/captcha/captcha.component.html rename to web/src/app/utils-components/captcha/captcha.component.html diff --git a/src/app/utils-components/captcha/captcha.component.scss b/web/src/app/utils-components/captcha/captcha.component.scss similarity index 100% rename from src/app/utils-components/captcha/captcha.component.scss rename to web/src/app/utils-components/captcha/captcha.component.scss diff --git a/src/app/utils-components/captcha/captcha.component.spec.ts b/web/src/app/utils-components/captcha/captcha.component.spec.ts similarity index 100% rename from src/app/utils-components/captcha/captcha.component.spec.ts rename to web/src/app/utils-components/captcha/captcha.component.spec.ts diff --git a/src/app/utils-components/captcha/captcha.component.ts b/web/src/app/utils-components/captcha/captcha.component.ts similarity index 100% rename from src/app/utils-components/captcha/captcha.component.ts rename to web/src/app/utils-components/captcha/captcha.component.ts diff --git a/src/app/utils-components/foi-fileinput/foi-fileinput.component.html b/web/src/app/utils-components/foi-fileinput/foi-fileinput.component.html similarity index 100% rename from src/app/utils-components/foi-fileinput/foi-fileinput.component.html rename to web/src/app/utils-components/foi-fileinput/foi-fileinput.component.html diff --git a/src/app/utils-components/foi-fileinput/foi-fileinput.component.scss b/web/src/app/utils-components/foi-fileinput/foi-fileinput.component.scss similarity index 100% rename from src/app/utils-components/foi-fileinput/foi-fileinput.component.scss rename to web/src/app/utils-components/foi-fileinput/foi-fileinput.component.scss diff --git a/src/app/utils-components/foi-fileinput/foi-fileinput.component.spec.ts b/web/src/app/utils-components/foi-fileinput/foi-fileinput.component.spec.ts similarity index 100% rename from src/app/utils-components/foi-fileinput/foi-fileinput.component.spec.ts rename to web/src/app/utils-components/foi-fileinput/foi-fileinput.component.spec.ts diff --git a/src/app/utils-components/foi-fileinput/foi-fileinput.component.ts b/web/src/app/utils-components/foi-fileinput/foi-fileinput.component.ts similarity index 100% rename from src/app/utils-components/foi-fileinput/foi-fileinput.component.ts rename to web/src/app/utils-components/foi-fileinput/foi-fileinput.component.ts diff --git a/src/app/utils-components/foi-valid/foi-valid.component.html b/web/src/app/utils-components/foi-valid/foi-valid.component.html similarity index 100% rename from src/app/utils-components/foi-valid/foi-valid.component.html rename to web/src/app/utils-components/foi-valid/foi-valid.component.html diff --git a/src/app/utils-components/foi-valid/foi-valid.component.scss b/web/src/app/utils-components/foi-valid/foi-valid.component.scss similarity index 100% rename from src/app/utils-components/foi-valid/foi-valid.component.scss rename to web/src/app/utils-components/foi-valid/foi-valid.component.scss diff --git a/src/app/utils-components/foi-valid/foi-valid.component.spec.ts b/web/src/app/utils-components/foi-valid/foi-valid.component.spec.ts similarity index 100% rename from src/app/utils-components/foi-valid/foi-valid.component.spec.ts rename to web/src/app/utils-components/foi-valid/foi-valid.component.spec.ts diff --git a/src/app/utils-components/foi-valid/foi-valid.component.ts b/web/src/app/utils-components/foi-valid/foi-valid.component.ts similarity index 100% rename from src/app/utils-components/foi-valid/foi-valid.component.ts rename to web/src/app/utils-components/foi-valid/foi-valid.component.ts diff --git a/src/app/utils-components/static-contact-block/static-contact-block.component.html b/web/src/app/utils-components/static-contact-block/static-contact-block.component.html similarity index 100% rename from src/app/utils-components/static-contact-block/static-contact-block.component.html rename to web/src/app/utils-components/static-contact-block/static-contact-block.component.html diff --git a/src/app/utils-components/static-contact-block/static-contact-block.component.scss b/web/src/app/utils-components/static-contact-block/static-contact-block.component.scss similarity index 100% rename from src/app/utils-components/static-contact-block/static-contact-block.component.scss rename to web/src/app/utils-components/static-contact-block/static-contact-block.component.scss diff --git a/src/app/utils-components/static-contact-block/static-contact-block.component.spec.ts b/web/src/app/utils-components/static-contact-block/static-contact-block.component.spec.ts similarity index 100% rename from src/app/utils-components/static-contact-block/static-contact-block.component.spec.ts rename to web/src/app/utils-components/static-contact-block/static-contact-block.component.spec.ts diff --git a/src/app/utils-components/static-contact-block/static-contact-block.component.ts b/web/src/app/utils-components/static-contact-block/static-contact-block.component.ts similarity index 100% rename from src/app/utils-components/static-contact-block/static-contact-block.component.ts rename to web/src/app/utils-components/static-contact-block/static-contact-block.component.ts diff --git a/src/app/utils-components/utils-components.module.ts b/web/src/app/utils-components/utils-components.module.ts similarity index 100% rename from src/app/utils-components/utils-components.module.ts rename to web/src/app/utils-components/utils-components.module.ts diff --git a/src/assets/.gitkeep b/web/src/assets/.gitkeep similarity index 100% rename from src/assets/.gitkeep rename to web/src/assets/.gitkeep diff --git a/src/assets/fonts/MyriadWebPro.ttf b/web/src/assets/fonts/MyriadWebPro.ttf similarity index 100% rename from src/assets/fonts/MyriadWebPro.ttf rename to web/src/assets/fonts/MyriadWebPro.ttf diff --git a/src/assets/images/bc_logo_transparent.png b/web/src/assets/images/bc_logo_transparent.png similarity index 100% rename from src/assets/images/bc_logo_transparent.png rename to web/src/assets/images/bc_logo_transparent.png diff --git a/src/assets/images/gov3_bc_logo.png b/web/src/assets/images/gov3_bc_logo.png similarity index 100% rename from src/assets/images/gov3_bc_logo.png rename to web/src/assets/images/gov3_bc_logo.png diff --git a/src/browserslist b/web/src/browserslist similarity index 100% rename from src/browserslist rename to web/src/browserslist diff --git a/src/environments/environment.prod.ts b/web/src/environments/environment.prod.ts similarity index 100% rename from src/environments/environment.prod.ts rename to web/src/environments/environment.prod.ts diff --git a/src/environments/environment.ts b/web/src/environments/environment.ts similarity index 100% rename from src/environments/environment.ts rename to web/src/environments/environment.ts diff --git a/src/favicon.ico b/web/src/favicon.ico similarity index 100% rename from src/favicon.ico rename to web/src/favicon.ico diff --git a/src/index.html b/web/src/index.html similarity index 100% rename from src/index.html rename to web/src/index.html diff --git a/src/karma.conf.js b/web/src/karma.conf.js similarity index 100% rename from src/karma.conf.js rename to web/src/karma.conf.js diff --git a/src/main.ts b/web/src/main.ts similarity index 100% rename from src/main.ts rename to web/src/main.ts diff --git a/src/polyfills.ts b/web/src/polyfills.ts similarity index 100% rename from src/polyfills.ts rename to web/src/polyfills.ts diff --git a/src/proxy.conf.json b/web/src/proxy.conf.json similarity index 100% rename from src/proxy.conf.json rename to web/src/proxy.conf.json diff --git a/src/styles.scss b/web/src/styles.scss similarity index 100% rename from src/styles.scss rename to web/src/styles.scss diff --git a/src/test.ts b/web/src/test.ts similarity index 100% rename from src/test.ts rename to web/src/test.ts diff --git a/src/tsconfig.app.json b/web/src/tsconfig.app.json similarity index 100% rename from src/tsconfig.app.json rename to web/src/tsconfig.app.json diff --git a/src/tsconfig.spec.json b/web/src/tsconfig.spec.json similarity index 100% rename from src/tsconfig.spec.json rename to web/src/tsconfig.spec.json diff --git a/src/tslint.json b/web/src/tslint.json similarity index 100% rename from src/tslint.json rename to web/src/tslint.json diff --git a/src/typings.d.ts b/web/src/typings.d.ts similarity index 100% rename from src/typings.d.ts rename to web/src/typings.d.ts diff --git a/tsconfig.json b/web/tsconfig.json similarity index 100% rename from tsconfig.json rename to web/tsconfig.json diff --git a/tslint.json b/web/tslint.json similarity index 100% rename from tslint.json rename to web/tslint.json From 32b2dbc14bbd4d8198dfc64a408e7a9c3f17289e Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Tue, 16 Feb 2021 11:55:24 -0800 Subject: [PATCH 102/589] Add default code owners file --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000..915e7c03 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,3 @@ +* @jleach +api/* @jleach +web/* @jleach From b637f62144bc63160eb9fe46c70b1ea5151182c6 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Tue, 16 Feb 2021 12:01:21 -0800 Subject: [PATCH 103/589] Initial work on new templates --- .../angular-app/angular-app.json | 0 .../angular-on-nginx-build.json | 0 .../angular-on-nginx-deploy.json | 0 .../angular-on-nginx/log-volume-create.json | 0 .../nginx-runtime/Dockerfile | 0 .../nginx-runtime/nginx-runtime.json | 0 .../nginx-runtime/nginx.conf.template | 0 .../nginx-runtime/s2i/bin/assemble | 0 .../nginx-runtime/s2i/bin/assemble-runtime | 0 .../nginx-runtime/s2i/bin/run | 0 openshift/templates/api-build.yaml | 118 ++++++++++++++++++ openshift/templates/cicd.yaml | 113 +++++++++++++++++ openshift/templates/web-build.yaml | 118 ++++++++++++++++++ 13 files changed, 349 insertions(+) rename openshift/{templates => templates.old}/angular-app/angular-app.json (100%) rename openshift/{templates => templates.old}/angular-on-nginx/angular-on-nginx-build.json (100%) rename openshift/{templates => templates.old}/angular-on-nginx/angular-on-nginx-deploy.json (100%) rename openshift/{templates => templates.old}/angular-on-nginx/log-volume-create.json (100%) rename openshift/{templates => templates.old}/nginx-runtime/Dockerfile (100%) rename openshift/{templates => templates.old}/nginx-runtime/nginx-runtime.json (100%) rename openshift/{templates => templates.old}/nginx-runtime/nginx.conf.template (100%) rename openshift/{templates => templates.old}/nginx-runtime/s2i/bin/assemble (100%) rename openshift/{templates => templates.old}/nginx-runtime/s2i/bin/assemble-runtime (100%) rename openshift/{templates => templates.old}/nginx-runtime/s2i/bin/run (100%) create mode 100644 openshift/templates/api-build.yaml create mode 100644 openshift/templates/cicd.yaml create mode 100644 openshift/templates/web-build.yaml diff --git a/openshift/templates/angular-app/angular-app.json b/openshift/templates.old/angular-app/angular-app.json similarity index 100% rename from openshift/templates/angular-app/angular-app.json rename to openshift/templates.old/angular-app/angular-app.json diff --git a/openshift/templates/angular-on-nginx/angular-on-nginx-build.json b/openshift/templates.old/angular-on-nginx/angular-on-nginx-build.json similarity index 100% rename from openshift/templates/angular-on-nginx/angular-on-nginx-build.json rename to openshift/templates.old/angular-on-nginx/angular-on-nginx-build.json diff --git a/openshift/templates/angular-on-nginx/angular-on-nginx-deploy.json b/openshift/templates.old/angular-on-nginx/angular-on-nginx-deploy.json similarity index 100% rename from openshift/templates/angular-on-nginx/angular-on-nginx-deploy.json rename to openshift/templates.old/angular-on-nginx/angular-on-nginx-deploy.json diff --git a/openshift/templates/angular-on-nginx/log-volume-create.json b/openshift/templates.old/angular-on-nginx/log-volume-create.json similarity index 100% rename from openshift/templates/angular-on-nginx/log-volume-create.json rename to openshift/templates.old/angular-on-nginx/log-volume-create.json diff --git a/openshift/templates/nginx-runtime/Dockerfile b/openshift/templates.old/nginx-runtime/Dockerfile similarity index 100% rename from openshift/templates/nginx-runtime/Dockerfile rename to openshift/templates.old/nginx-runtime/Dockerfile diff --git a/openshift/templates/nginx-runtime/nginx-runtime.json b/openshift/templates.old/nginx-runtime/nginx-runtime.json similarity index 100% rename from openshift/templates/nginx-runtime/nginx-runtime.json rename to openshift/templates.old/nginx-runtime/nginx-runtime.json diff --git a/openshift/templates/nginx-runtime/nginx.conf.template b/openshift/templates.old/nginx-runtime/nginx.conf.template similarity index 100% rename from openshift/templates/nginx-runtime/nginx.conf.template rename to openshift/templates.old/nginx-runtime/nginx.conf.template diff --git a/openshift/templates/nginx-runtime/s2i/bin/assemble b/openshift/templates.old/nginx-runtime/s2i/bin/assemble similarity index 100% rename from openshift/templates/nginx-runtime/s2i/bin/assemble rename to openshift/templates.old/nginx-runtime/s2i/bin/assemble diff --git a/openshift/templates/nginx-runtime/s2i/bin/assemble-runtime b/openshift/templates.old/nginx-runtime/s2i/bin/assemble-runtime similarity index 100% rename from openshift/templates/nginx-runtime/s2i/bin/assemble-runtime rename to openshift/templates.old/nginx-runtime/s2i/bin/assemble-runtime diff --git a/openshift/templates/nginx-runtime/s2i/bin/run b/openshift/templates.old/nginx-runtime/s2i/bin/run similarity index 100% rename from openshift/templates/nginx-runtime/s2i/bin/run rename to openshift/templates.old/nginx-runtime/s2i/bin/run diff --git a/openshift/templates/api-build.yaml b/openshift/templates/api-build.yaml new file mode 100644 index 00000000..c822c265 --- /dev/null +++ b/openshift/templates/api-build.yaml @@ -0,0 +1,118 @@ +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + labels: + app: ${NAME}-api + name: ${NAME}-build + namespace: devhub-dev +objects: +- apiVersion: v1 + kind: ImageStream + metadata: + name: ${NAME}-api + labels: + app: ${NAME}-api +- apiVersion: v1 + kind: BuildConfig + metadata: + name: ${NAME}-api-${GIT_REF}-build + labels: + app: ${NAME}-api + name: ${NAME}-api-${GIT_REF}-build + spec: + output: + to: + kind: ImageStreamTag + name: ${NAME}-api:${OUTPUT_IMAGE_TAG} + resources: + limits: + cpu: ${CPU_LIMIT} + memory: ${MEMORY_LIMIT} + requests: + cpu: ${CPU_REQUEST} + memory: ${MEMORY_REQUEST} + runPolicy: Serial + source: + contextDir: ${SOURCE_CONTEXT_DIR} + git: + ref: ${GIT_REF} + uri: ${GIT_REPO_URL} + type: Git + strategy: + sourceStrategy: + env: + - name: BUILD_LOGLEVEL + value: "5" + from: + kind: ImageStreamTag + name: ${SOURCE_IMAGE_NAME}:${SOURCE_IMAGE_TAG} + namespace: ${SOURCE_IMAGE_NAMESPACE} + incremental: false + type: Source + triggers: + - type: ConfigChange +parameters: +- description: | + The name assigned to all of the objects defined in this template. + You should keep this as default unless your know what your doing. + displayName: Name + name: NAME + required: true + value: foi-request +- description: | + The URL to your GIT repo, don't use the this default unless + your just experimenting. + displayName: Git Repo URL + name: GIT_REPO_URL + required: true + value: https://github.com/bcgov/foi-requests.git +- description: The git reference or branch. + displayName: Git Reference + name: GIT_REF + required: true + value: master +- description: The source context directory. + displayName: Source Context Directory + name: SOURCE_CONTEXT_DIR + required: false + value: "api" +- description: The tag given to the built image. + displayName: Output Image Tag + name: OUTPUT_IMAGE_TAG + required: true + value: latest +- description: The openshift project where builds and target images are stored. + displayName: Build Project + name: SOURCE_IMAGE_NAMESPACE + value: 'openshift' + required: true +- description: The name of the source image. + displayName: Source Image Name + name: SOURCE_IMAGE_NAME + value: 'nodejs' + required: true +- description: The tag of the source image. + displayName: Source Image Tag + name: SOURCE_IMAGE_TAG + value: "10" + required: true +- description: The resources CPU limit (in cores) for this build. + displayName: Resources CPU Limit + name: CPU_LIMIT + required: true + value: "2" +- description: The resources Memory limit (in Mi, Gi, etc) for this build. + displayName: Resources Memory Limit + name: MEMORY_LIMIT + required: true + value: 2Gi +- description: The resources CPU request (in cores) for this build. + displayName: Resources CPU Request + name: CPU_REQUEST + required: true + value: "1" +- description: The resources Memory request (in Mi, Gi, etc) for this build. + displayName: Resources Memory Request + name: MEMORY_REQUEST + required: true + value: 2Gi diff --git a/openshift/templates/cicd.yaml b/openshift/templates/cicd.yaml new file mode 100644 index 00000000..29834353 --- /dev/null +++ b/openshift/templates/cicd.yaml @@ -0,0 +1,113 @@ +# Copyright 2020 The Province of British Columbia +# +# Licensed 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. +# +--- +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + name: github-cicd-credentials +objects: + - apiVersion: v1 + kind: ServiceAccount + metadata: + name: ${NAME} + labels: + app: ${NAME} + - apiVersion: authorization.openshift.io/v1 + kind: Role + metadata: + name: ${NAME} + labels: + app: ${NAME} + rules: + - apiGroups: + - build.openshift.io + - "" + resources: + - buildconfigs/instantiate + verbs: + - create + - apiGroups: + - build.openshift.io + - "" + resources: + - buildconfigs + - builds + verbs: + - create + - get + - list + - apiGroups: + - image.openshift.io + - "" + resources: + - imagestreams + - imagestreamimages + verbs: + - get + - list + - apiGroups: + - image.openshift.io + - "" + resources: + - imagestreamtags + verbs: + - create + - get + - list + - apiGroups: + - image.openshift.io + - "" + resources: + - imagestreams + verbs: + - get + - list + - apiGroups: + - build.openshift.io + - "" + resources: + - builds/log + verbs: + - get + - list + - watch + - apiVersion: authorization.openshift.io/v1 + kind: RoleBinding + metadata: + name: ${NAME} + labels: + app: ${NAME} + subjects: + - kind: ServiceAccount + name: ${NAME} + roleRef: + kind: Role + name: ${NAME} + namespace: ${NAMESPACE} + apiGroup: authorization.openshift.io +parameters: + - displayName: Namespace + description: | + The namespace where all of components of the + credentials are stored. + name: NAMESPACE + required: true + - displayName: Credentials Name + description: | + The name used for all components of the + credentials. + name: NAME + required: true + value: github-cicd diff --git a/openshift/templates/web-build.yaml b/openshift/templates/web-build.yaml new file mode 100644 index 00000000..633d4080 --- /dev/null +++ b/openshift/templates/web-build.yaml @@ -0,0 +1,118 @@ +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + labels: + app: ${NAME}-web + name: ${NAME}-build + namespace: devhub-dev +objects: +- apiVersion: v1 + kind: ImageStream + metadata: + name: ${NAME}-web + labels: + app: ${NAME}-web +- apiVersion: v1 + kind: BuildConfig + metadata: + name: ${NAME}-web-${GIT_REF}-build + labels: + app: ${NAME}-web + name: ${NAME}-web-${GIT_REF}-build + spec: + output: + to: + kind: ImageStreamTag + name: ${NAME}-web:${OUTPUT_IMAGE_TAG} + resources: + limits: + cpu: ${CPU_LIMIT} + memory: ${MEMORY_LIMIT} + requests: + cpu: ${CPU_REQUEST} + memory: ${MEMORY_REQUEST} + runPolicy: Serial + source: + contextDir: ${SOURCE_CONTEXT_DIR} + git: + ref: ${GIT_REF} + uri: ${GIT_REPO_URL} + type: Git + strategy: + sourceStrategy: + env: + - name: BUILD_LOGLEVEL + value: "5" + from: + kind: ImageStreamTag + name: ${SOURCE_IMAGE_NAME}:${SOURCE_IMAGE_TAG} + namespace: ${SOURCE_IMAGE_NAMESPACE} + incremental: false + type: Source + triggers: + - type: ConfigChange +parameters: +- description: | + The name assigned to all of the objects defined in this template. + You should keep this as default unless your know what your doing. + displayName: Name + name: NAME + required: true + value: foi-request +- description: | + The URL to your GIT repo, don't use the this default unless + your just experimenting. + displayName: Git Repo URL + name: GIT_REPO_URL + required: true + value: https://github.com/bcgov/foi-requests.git +- description: The git reference or branch. + displayName: Git Reference + name: GIT_REF + required: true + value: master +- description: The source context directory. + displayName: Source Context Directory + name: SOURCE_CONTEXT_DIR + required: false + value: "web" +- description: The tag given to the built image. + displayName: Output Image Tag + name: OUTPUT_IMAGE_TAG + required: true + value: latest +- description: The openshift project where builds and target images are stored. + displayName: Build Project + name: SOURCE_IMAGE_NAMESPACE + # value: 'openshift' + required: true +- description: The name of the source image. + displayName: Source Image Name + name: SOURCE_IMAGE_NAME + value: 'caddy-s2i-builder' + required: true +- description: The tag of the source image. + displayName: Source Image Tag + name: SOURCE_IMAGE_TAG + value: "latest" + required: true +- description: The resources CPU limit (in cores) for this build. + displayName: Resources CPU Limit + name: CPU_LIMIT + required: true + value: "2" +- description: The resources Memory limit (in Mi, Gi, etc) for this build. + displayName: Resources Memory Limit + name: MEMORY_LIMIT + required: true + value: 2Gi +- description: The resources CPU request (in cores) for this build. + displayName: Resources CPU Request + name: CPU_REQUEST + required: true + value: "1" +- description: The resources Memory request (in Mi, Gi, etc) for this build. + displayName: Resources Memory Request + name: MEMORY_REQUEST + required: true + value: 2Gi From 68f2e83701919f82411f29a1aeb3d1a52b38d045 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Tue, 16 Feb 2021 12:24:39 -0800 Subject: [PATCH 104/589] Work on API build --- .github/workflows/api.yml | 79 ++++++++++++++++++++++++ openshift/templates/api-build.yaml | 99 +++++------------------------- openshift/templates/nsp-tools.yaml | 86 ++++++++++++++++++++++++++ 3 files changed, 182 insertions(+), 82 deletions(-) create mode 100644 .github/workflows/api.yml create mode 100644 openshift/templates/nsp-tools.yaml diff --git a/.github/workflows/api.yml b/.github/workflows/api.yml new file mode 100644 index 00000000..45f79f35 --- /dev/null +++ b/.github/workflows/api.yml @@ -0,0 +1,79 @@ +name: Test & Build API +on: + push: + paths: + - "api/src/**/*.js" + - "api/package*.json" + workflow_dispatch: +defaults: + run: + working-directory: ./api +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - uses: actions/setup-node@master + with: + node-version: "12" + - name: Install dependencies + run: npm ci + - name: Unit tests w/ coverage + run: npm run test:coverage + - name: LINTing + run: npm run test:lint + # - name: OpenAPI Schema + # run: npm run test:schema + # - name: Upload coverage report + # env: + # CC_TEST_REPORTER_ID: ${{ secrets.TestReporterID }} + # CI: "true" + # run: | + # curl -Ls https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + # chmod +x ./cc-test-reporter + # ./cc-test-reporter format-coverage -t lcov -o codeclimate.json + # ./cc-test-reporter upload-coverage -i codeclimate.json + build: + runs-on: ubuntu-latest + needs: [test] + strategy: + matrix: + node-version: [10.x, 12.x] + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Cache node modules + uses: actions/cache@v1 + with: + path: node_modules + key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.OS }}-build-${{ env.cache-name }}- + ${{ runner.OS }}-build- + ${{ runner.OS }}- + - name: npm install and build + run: | + npm ci + npm run build --if-present + env: + CI: "true" + s2i-build: + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + needs: [test, build] + steps: + - name: Image Build + env: + NAMESPACE: 04d1a3-tools + BUILD_NAME: api-master-build + IMAGE_NAME: api + uses: redhat-developer/openshift-actions@v1.1 + with: + version: "latest" + openshift_server_url: ${{secrets.OpenShiftServerURL}} + parameters: '{"apitoken": "${{secrets.OpenShiftToken}}", "acceptUntrustedCerts": "true"}' + cmd: | + 'version' + 'start-build ${BUILD_NAME} -n ${NAMESPACE} --follow' diff --git a/openshift/templates/api-build.yaml b/openshift/templates/api-build.yaml index c822c265..159a70ee 100644 --- a/openshift/templates/api-build.yaml +++ b/openshift/templates/api-build.yaml @@ -2,41 +2,41 @@ apiVersion: template.openshift.io/v1 kind: Template metadata: labels: - app: ${NAME}-api - name: ${NAME}-build + app: foi-request-api + name: api-build namespace: devhub-dev objects: - apiVersion: v1 kind: ImageStream metadata: - name: ${NAME}-api + name: api labels: - app: ${NAME}-api + app: foi-request-api - apiVersion: v1 kind: BuildConfig metadata: - name: ${NAME}-api-${GIT_REF}-build + name: api-master-build labels: - app: ${NAME}-api - name: ${NAME}-api-${GIT_REF}-build + app: foi-request-api + name: api-master-build spec: output: to: kind: ImageStreamTag - name: ${NAME}-api:${OUTPUT_IMAGE_TAG} + name: api:latest resources: limits: - cpu: ${CPU_LIMIT} - memory: ${MEMORY_LIMIT} + cpu: 2 + memory: 2Gi requests: - cpu: ${CPU_REQUEST} - memory: ${MEMORY_REQUEST} + cpu: 2 + memory: 1Gi runPolicy: Serial source: - contextDir: ${SOURCE_CONTEXT_DIR} + contextDir: api git: - ref: ${GIT_REF} - uri: ${GIT_REPO_URL} + ref: master + uri: https://github.com/bcgov/foi-requests.git type: Git strategy: sourceStrategy: @@ -45,74 +45,9 @@ objects: value: "5" from: kind: ImageStreamTag - name: ${SOURCE_IMAGE_NAME}:${SOURCE_IMAGE_TAG} - namespace: ${SOURCE_IMAGE_NAMESPACE} + name: nodejs:10 + namespace: openshift incremental: false type: Source triggers: - type: ConfigChange -parameters: -- description: | - The name assigned to all of the objects defined in this template. - You should keep this as default unless your know what your doing. - displayName: Name - name: NAME - required: true - value: foi-request -- description: | - The URL to your GIT repo, don't use the this default unless - your just experimenting. - displayName: Git Repo URL - name: GIT_REPO_URL - required: true - value: https://github.com/bcgov/foi-requests.git -- description: The git reference or branch. - displayName: Git Reference - name: GIT_REF - required: true - value: master -- description: The source context directory. - displayName: Source Context Directory - name: SOURCE_CONTEXT_DIR - required: false - value: "api" -- description: The tag given to the built image. - displayName: Output Image Tag - name: OUTPUT_IMAGE_TAG - required: true - value: latest -- description: The openshift project where builds and target images are stored. - displayName: Build Project - name: SOURCE_IMAGE_NAMESPACE - value: 'openshift' - required: true -- description: The name of the source image. - displayName: Source Image Name - name: SOURCE_IMAGE_NAME - value: 'nodejs' - required: true -- description: The tag of the source image. - displayName: Source Image Tag - name: SOURCE_IMAGE_TAG - value: "10" - required: true -- description: The resources CPU limit (in cores) for this build. - displayName: Resources CPU Limit - name: CPU_LIMIT - required: true - value: "2" -- description: The resources Memory limit (in Mi, Gi, etc) for this build. - displayName: Resources Memory Limit - name: MEMORY_LIMIT - required: true - value: 2Gi -- description: The resources CPU request (in cores) for this build. - displayName: Resources CPU Request - name: CPU_REQUEST - required: true - value: "1" -- description: The resources Memory request (in Mi, Gi, etc) for this build. - displayName: Resources Memory Request - name: MEMORY_REQUEST - required: true - value: 2Gi diff --git a/openshift/templates/nsp-tools.yaml b/openshift/templates/nsp-tools.yaml new file mode 100644 index 00000000..cb038edf --- /dev/null +++ b/openshift/templates/nsp-tools.yaml @@ -0,0 +1,86 @@ +--- +apiVersion: template.openshift.io/v1 +kind: Template +labels: + template: quickstart-network-security-policy +metadata: + name: quickstart-network-security-policy +objects: + - kind: NetworkPolicy + apiVersion: networking.k8s.io/v1 + metadata: + name: deny-by-default + spec: + # The default posture for a security first namespace is to + # deny all traffic. If not added this rule will be added + # by Platform Services during environment cut-over. + podSelector: {} + ingress: [] + - apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + metadata: + name: allow-from-openshift-ingress + spec: + # This policy allows any pod with a route & service combination + # to accept traffic from the OpenShift router pods. This is + # required for things outside of OpenShift (like the Internet) + # to reach your pods. + ingress: + - from: + - namespaceSelector: + matchLabels: + network.openshift.io/policy-group: ingress + podSelector: {} + policyTypes: + - Ingress + - apiVersion: networking.k8s.io/v1 + kind: NetworkPolicy + metadata: + name: allow-all-internal + spec: + # Allow all pods within the current namespace to communicate + # to one another. + ingress: + - from: + - namespaceSelector: + matchLabels: + environment: ${ENVIRONMENT} + name: ${NAMESPACE_PREFIX} + podSelector: {} + policyTypes: + - Ingress + - apiVersion: security.devops.gov.bc.ca/v1alpha1 + kind: NetworkSecurityPolicy + metadata: + name: any-to-any + spec: + description: | + allow all pods to communicate + source: + - - "$namespace=${NAMESPACE_PREFIX}-${ENVIRONMENT}" + destination: + - - "$namespace=*" + - apiVersion: security.devops.gov.bc.ca/v1alpha1 + kind: NetworkSecurityPolicy + metadata: + name: any-to-external + spec: + description: | + Allow all pods to talk to external systems + source: + - - "$namespace=${NAMESPACE_PREFIX}-${ENVIRONMENT}" + destination: + - - "ext:network=any" +parameters: + - name: NAMESPACE_PREFIX + displayName: Namespace Prefix + description: | + The prefix (a.k.a license plate) of the namespace this policy + is being deployed to; + required: true + - name: ENVIRONMENT + displayName: Environment Name + description: | + The environment (i.e dev/test/prod/tools) this policy is + being deployed to. + required: true \ No newline at end of file From 7a04b539eb7ea1f075bbf7ffa6701727a168d588 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Tue, 16 Feb 2021 12:28:36 -0800 Subject: [PATCH 105/589] Work on gh workflow --- .github/workflows/api.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/api.yml b/.github/workflows/api.yml index 45f79f35..81b52aa7 100644 --- a/.github/workflows/api.yml +++ b/.github/workflows/api.yml @@ -19,9 +19,11 @@ jobs: - name: Install dependencies run: npm ci - name: Unit tests w/ coverage - run: npm run test:coverage - - name: LINTing - run: npm run test:lint + run: npm run test + # - name: Unit tests w/ coverage + # run: npm run test:coverage + # - name: LINTing + # run: npm run test:lint # - name: OpenAPI Schema # run: npm run test:schema # - name: Upload coverage report From 318c38d59b950466f70c4fe5e8e1ac160bb702ce Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Tue, 16 Feb 2021 12:29:52 -0800 Subject: [PATCH 106/589] Fix job title --- .github/workflows/api.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/api.yml b/.github/workflows/api.yml index 81b52aa7..6caca12e 100644 --- a/.github/workflows/api.yml +++ b/.github/workflows/api.yml @@ -18,7 +18,7 @@ jobs: node-version: "12" - name: Install dependencies run: npm ci - - name: Unit tests w/ coverage + - name: Unit tests w/o coverage run: npm run test # - name: Unit tests w/ coverage # run: npm run test:coverage From d15e220fc4b75d2b573681481869d9e34d7d3276 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Tue, 16 Feb 2021 13:06:58 -0800 Subject: [PATCH 107/589] Fix node version --- .github/workflows/api.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/api.yml b/.github/workflows/api.yml index 6caca12e..f556aced 100644 --- a/.github/workflows/api.yml +++ b/.github/workflows/api.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@master - uses: actions/setup-node@master with: - node-version: "12" + node-version: "10" - name: Install dependencies run: npm ci - name: Unit tests w/o coverage @@ -40,7 +40,7 @@ jobs: needs: [test] strategy: matrix: - node-version: [10.x, 12.x] + node-version: [10.x] steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 From d5cd3b32941ab15b95bb3d0d4f14a9dea899ebc8 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Thu, 4 Mar 2021 11:41:35 -0800 Subject: [PATCH 108/589] Cleanup build scripts --- web/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/package.json b/web/package.json index defa8c15..8e96cbbf 100644 --- a/web/package.json +++ b/web/package.json @@ -13,8 +13,7 @@ "cov": "http-server -c-1 -o -p 9875 ./coverage/bcfoi", "test-cov": "concurrently \"http-server -c-1 -o -p 9875 ./coverage/bcfoi\" \"ng test --code-coverage\" ", "lint": "ng lint", - "e2e": "ng e2e", - "postinstall": "cd api && npm install" + "e2e": "ng e2e" }, "private": true, "dependencies": { From e28ab0303c0368088589b0ef8ef72a08a5d9aacf Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Thu, 4 Mar 2021 12:56:36 -0800 Subject: [PATCH 109/589] Move old s2i --- .gitignore | 2 +- {.s2i => s2i.old}/bin/assemble | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {.s2i => s2i.old}/bin/assemble (100%) diff --git a/.gitignore b/.gitignore index aa17de32..53b1323c 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ /out-tsc # dependencies -/node_modules +node_modules # profiling files chrome-profiler-events.json diff --git a/.s2i/bin/assemble b/s2i.old/bin/assemble similarity index 100% rename from .s2i/bin/assemble rename to s2i.old/bin/assemble From d730b9cb1a2ae6622769895c01e4d97da8e1fe68 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Fri, 5 Mar 2021 09:08:11 -0800 Subject: [PATCH 110/589] Work on web build --- .github/workflows/web.yml | 75 +++++++++++++++++++++++ .gitignore | 2 +- csr_details.txt | 8 +-- openshift/templates/nsp-tools.yaml | 34 ++++------- openshift/templates/web-build.yaml | 97 +++++++++++++++++++++++++----- 5 files changed, 173 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/web.yml diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml new file mode 100644 index 00000000..e4243253 --- /dev/null +++ b/.github/workflows/web.yml @@ -0,0 +1,75 @@ +name: Test & Build +on: + push: + paths: + - "web/src/**/*.ts" + - "web/src/**/*.tsx" + - "web/package*.json" + - "web/public/**/*" + - "web/Caddyfile" +defaults: + run: + working-directory: ./web +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - uses: actions/setup-node@master + with: + node-version: "12" + - name: Install dependencies + run: npm ci + - name: Unit tests w/ coverage + run: npm run test -- --coverage --passWithNoTests + # - name: LINTing + # run: npm run test:lint + # - name: Upload coverage report + # env: + # CC_TEST_REPORTER_ID: ${{ secrets.TestReporterID }} + # CI: "true" + # run: | + # curl -Ls https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter + # chmod +x ./cc-test-reporter + # ./cc-test-reporter format-coverage -t lcov -o codeclimate.json + # ./cc-test-reporter upload-coverage -i codeclimate.json + build: + runs-on: ubuntu-latest + needs: [test] + strategy: + matrix: + node-version: [10.x, 12.x] + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - name: Cache node modules + uses: actions/cache@v1 + with: + path: node_modules + key: ${{ runner.OS }}-build-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + ${{ runner.OS }}-build-${{ env.cache-name }}- + ${{ runner.OS }}-build- + ${{ runner.OS }}- + - name: npm install and build + run: | + npm ci + npm run build --if-present + env: + CI: "true" + s2i-build: + if: github.event_name == 'push' && github.ref == 'refs/heads/master' + runs-on: ubuntu-latest + needs: [test, build] + steps: + - name: S2I Build + uses: redhat-developer/openshift-actions@v1.1 + with: + version: "latest" + openshift_server_url: ${{ secrets.OpenShiftServerURL}} + parameters: '{"apitoken": "${{ secrets.OpenShiftToken }}", "acceptUntrustedCerts": "true"}' + cmd: | + 'version' + 'start-build platsrv-registry-web-master-build --follow -n platform-registry-tools' diff --git a/.gitignore b/.gitignore index 53b1323c..fb6c0450 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ # See http://help.github.com/ignore-files/ for more about ignoring files. # compiled output -/dist +dist/ /tmp /out-tsc diff --git a/csr_details.txt b/csr_details.txt index 0c3a0973..585841d9 100644 --- a/csr_details.txt +++ b/csr_details.txt @@ -16,13 +16,13 @@ ST=British Columbia L=Victoria O=Government of the Province of British Columbia OU=Citizens' Services -CN=foi-request-form.gov.bc.ca +CN=foirequestform.gov.bc.ca emailAddress=jason.leach@gov.bc.ca [req_ext] subjectAltName=@alt_names [alt_names] -DNS.1=foi-request-form.gov.bc.ca -DNS.2=dev.foi-request-form.gov.bc.ca -DNS.3=test.foi-request-form.gov.bc.ca +DNS.1=foirequestform.gov.bc.ca +DNS.2=dev.foirequestform.gov.bc.ca +DNS.3=test.foirequestform.gov.bc.ca diff --git a/openshift/templates/nsp-tools.yaml b/openshift/templates/nsp-tools.yaml index cb038edf..a6baca46 100644 --- a/openshift/templates/nsp-tools.yaml +++ b/openshift/templates/nsp-tools.yaml @@ -33,22 +33,17 @@ objects: podSelector: {} policyTypes: - Ingress - - apiVersion: networking.k8s.io/v1 - kind: NetworkPolicy + - kind: NetworkPolicy + apiVersion: networking.k8s.io/v1 metadata: - name: allow-all-internal + name: allow-same-namespace spec: # Allow all pods within the current namespace to communicate # to one another. + podSelector: ingress: - - from: - - namespaceSelector: - matchLabels: - environment: ${ENVIRONMENT} - name: ${NAMESPACE_PREFIX} - podSelector: {} - policyTypes: - - Ingress + - from: + - podSelector: {} - apiVersion: security.devops.gov.bc.ca/v1alpha1 kind: NetworkSecurityPolicy metadata: @@ -57,7 +52,7 @@ objects: description: | allow all pods to communicate source: - - - "$namespace=${NAMESPACE_PREFIX}-${ENVIRONMENT}" + - - "$namespace=${NAMESPACE}" destination: - - "$namespace=*" - apiVersion: security.devops.gov.bc.ca/v1alpha1 @@ -68,19 +63,12 @@ objects: description: | Allow all pods to talk to external systems source: - - - "$namespace=${NAMESPACE_PREFIX}-${ENVIRONMENT}" + - - "$namespace=${NAMESPACE}" destination: - - "ext:network=any" parameters: - - name: NAMESPACE_PREFIX - displayName: Namespace Prefix + - name: NAMESPACE + displayName: Namespace description: | - The prefix (a.k.a license plate) of the namespace this policy - is being deployed to; + The namespace this policy is being deployed to; required: true - - name: ENVIRONMENT - displayName: Environment Name - description: | - The environment (i.e dev/test/prod/tools) this policy is - being deployed to. - required: true \ No newline at end of file diff --git a/openshift/templates/web-build.yaml b/openshift/templates/web-build.yaml index 633d4080..fd5ec6a2 100644 --- a/openshift/templates/web-build.yaml +++ b/openshift/templates/web-build.yaml @@ -1,29 +1,51 @@ +# Copyright 2020 The Province of British Columbia +# +# Licensed 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. +# +--- apiVersion: template.openshift.io/v1 kind: Template metadata: labels: - app: ${NAME}-web + app: ${NAME} name: ${NAME}-build - namespace: devhub-dev objects: - apiVersion: v1 kind: ImageStream metadata: - name: ${NAME}-web + name: ${NAME}-artifacts labels: - app: ${NAME}-web + app: ${NAME} +- apiVersion: v1 + kind: ImageStream + metadata: + name: ${NAME} + labels: + app: ${NAME} - apiVersion: v1 kind: BuildConfig metadata: - name: ${NAME}-web-${GIT_REF}-build + name: ${NAME}-artifact-build labels: - app: ${NAME}-web - name: ${NAME}-web-${GIT_REF}-build + app: ${NAME} + name: ${NAME}-artifact-build spec: + successfulBuildsHistoryLimit: 1 + failedBuildsHistoryLimit: 1 output: to: kind: ImageStreamTag - name: ${NAME}-web:${OUTPUT_IMAGE_TAG} + name: ${NAME}-artifacts:${OUTPUT_IMAGE_TAG} resources: limits: cpu: ${CPU_LIMIT} @@ -49,8 +71,53 @@ objects: namespace: ${SOURCE_IMAGE_NAMESPACE} incremental: false type: Source - triggers: - - type: ConfigChange + # triggers: + # - type: ConfigChange +- apiVersion: v1 + kind: BuildConfig + metadata: + name: ${NAME}-image-build + labels: + app: ${NAME} + name: ${NAME}-image-build + spec: + successfulBuildsHistoryLimit: 3 + failedBuildsHistoryLimit: 3 + output: + to: + kind: ImageStreamTag + name: ${NAME}:${OUTPUT_IMAGE_TAG} + resources: + limits: + cpu: ${CPU_LIMIT} + memory: ${MEMORY_LIMIT} + requests: + cpu: ${CPU_REQUEST} + memory: ${MEMORY_REQUEST} + runPolicy: Serial + source: + type: Dockerfile + dockerfile: |- + FROM image-registry.openshift-image-registry.svc:5000/04d1a3-tools/caddy-s2i-v2:latest + COPY bcfoi/* /opt/app-root/src + RUN ls -lah /opt/app-root/src + CMD /usr/libexec/s2i/run + images: + - from: + kind: ImageStreamTag + name: ${NAME}-artifacts:latest + paths: + - sourcePath: /opt/app-root/src/dist/bcfoi + destinationDir: "bcfoi" + strategy: + dockerStrategy: + from: + kind: DockerImage + name: image-registry.openshift-image-registry.svc:5000/04d1a3-tools/caddy-s2i-v2:latest + type: Docker + # triggers: + # - imageChange: {} + # type: ImageChange parameters: - description: | The name assigned to all of the objects defined in this template. @@ -58,7 +125,7 @@ parameters: displayName: Name name: NAME required: true - value: foi-request + value: web - description: | The URL to your GIT repo, don't use the this default unless your just experimenting. @@ -84,17 +151,17 @@ parameters: - description: The openshift project where builds and target images are stored. displayName: Build Project name: SOURCE_IMAGE_NAMESPACE - # value: 'openshift' + value: 'openshift' required: true - description: The name of the source image. displayName: Source Image Name name: SOURCE_IMAGE_NAME - value: 'caddy-s2i-builder' + value: 'nodejs' required: true - description: The tag of the source image. displayName: Source Image Tag name: SOURCE_IMAGE_TAG - value: "latest" + value: "10" required: true - description: The resources CPU limit (in cores) for this build. displayName: Resources CPU Limit @@ -105,7 +172,7 @@ parameters: displayName: Resources Memory Limit name: MEMORY_LIMIT required: true - value: 2Gi + value: 4Gi - description: The resources CPU request (in cores) for this build. displayName: Resources CPU Request name: CPU_REQUEST From 894455e6599b3a4840211f6afdf5e5cca2cb78cd Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Fri, 5 Mar 2021 11:30:46 -0800 Subject: [PATCH 111/589] Initial work on deployment --- openshift/templates/deploy.yaml | 387 ++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) create mode 100644 openshift/templates/deploy.yaml diff --git a/openshift/templates/deploy.yaml b/openshift/templates/deploy.yaml new file mode 100644 index 00000000..475cefe4 --- /dev/null +++ b/openshift/templates/deploy.yaml @@ -0,0 +1,387 @@ +# Copyright 2020 The Province of British Columbia +# +# Licensed 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. +# +--- +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + annotations: + description: | + Deployment template for the Platform Serices + RocketChat helper app reggie. + iconClass: icon-node + name: foi-request-form +objects: + - apiVersion: v1 + kind: ConfigMap + metadata: + name: api-config + labels: + app: foi-request-form + role: api + data: + FOI_REQUEST_API_PORT: ${FOI_REQUEST_API_PORT} + FOI_REQUEST_SMTP: ${FOI_REQUEST_SMTP} + FOI_REQUEST_SMTP_PORT: ${FOI_REQUEST_SMTP_PORT} + FOI_REQUEST_SMTP_SECURE: ${FOI_REQUEST_SMTP_SECURE} + FOI_REQUEST_INBOX: ${FOI_REQUEST_INBOX} + FOI_REQUEST_SENDER: ${FOI_REQUEST_SENDER} + FOI_KC_REALM: ${FOI_KC_REALM} + FOI_KC_URL: ${FOI_KC_URL} + FOI_KC_CLIENTID: ${FOI_KC_CLIENTID} + FOI_KC_SECRET: ${FOI_KC_SECRET} + FOI_KC_SSL_REQUIRED: ${FOI_KC_SSL_REQUIRED} + FOI_KC_PUBLIC_CLIENT: ${FOI_KC_PUBLIC_CLIENT} + JWKS_URI: ${JWKS_URI} + - apiVersion: v1 + kind: ConfigMap + metadata: + name: web-caddy-config + labels: + app: foi-request-form + role: web + data: + Caddyfile: | + # Where caddy should listen + :2015 + + # Turn on the Web/file server + file_server + templates { + mime "text/javascript" "application/javascript" + } + + # The site root + root * /opt/app-root/src/ + + # Because we should + encode zstd gzip + + # This rewrite rule may be required to get React apps + # to deal with trailing slashes properly. + #@filter { + # not path_regexp ^\/0.0.0.0 + # file { + # try_files {path} {path}/ /?url={uri} + # } + #} + #rewrite @try_files {http.matchers.file.relative} + + # This properly deals with react routes. + try_files {path} {path}/ /index.html + + # On OCP we should log to stdout so Prometheus can + # slurp up the logs for human consumption. + log { + #errors stdout + output stdout + format single_field common_log + level info + } + - apiVersion: v1 + kind: Route + metadata: + name: api + annotations: + description: Route for reggies API services + labels: + app: foi-request-form + role: api + spec: + host: "${HOSTNAME_HTTPS}" + path: /api + port: + targetPort: 7085-tcp + to: + kind: Service + name: api + tls: + termination: edge + insecureEdgeTerminationPolicy: Redirect + certificate: |- + ${TLS_CERT_PEM} + key: |- + ${TLS_KEY_PEM} + caCertificate: |- + ${TLS_CACERT_PEM} + - apiVersion: v1 + kind: Route + metadata: + name: web + annotations: + description: Route for reggies Web front end + labels: + app: foi-request-form + role: web + spec: + host: "${HOSTNAME_HTTPS}" + port: + targetPort: 2015-tcp + to: + kind: Service + name: web + tls: + termination: edge + insecureEdgeTerminationPolicy: Redirect + certificate: |- + ${TLS_CERT_PEM} + key: |- + ${TLS_KEY_PEM} + caCertificate: |- + ${TLS_CACERT_PEM} + - apiVersion: v1 + kind: Service + metadata: + labels: + app: foi-request-form + role: api + name: api + spec: + selector: + app: foi-request-form + role: api + ports: + - name: 8000-tcp + port: 8000 + protocol: TCP + targetPort: 8000 + - apiVersion: v1 + kind: Service + metadata: + labels: + app: foi-request-form + role: web + name: web + spec: + selector: + app: foi-request-form + role: web + ports: + - name: 2015-tcp + port: 2015 + protocol: TCP + targetPort: 2015 + - apiVersion: v1 + kind: DeploymentConfig + metadata: + labels: + app: foi-request-form + role: api + name: api + spec: + strategy: + type: Rolling + triggers: + - type: ConfigChange + - type: ImageChange + imageChangeParams: + automatic: true + containerNames: + - api + from: + kind: ImageStreamTag + name: "api:${API_SOURCE_IMAGE_TAG}" + namespace: ${SOURCE_IMAGE_NAMESPACE} + replicas: ${{REPLICA_COUNT}} + selector: + app: foi-request-form + role: api + template: + metadata: + labels: + app: foi-request-form + role: api + name: foi-request-form + spec: + containers: + - name: api + image: " " + # startupProbe: + # httpGet: + # path: /api/v1/ehlo + # port: 8000 + # failureThreshold: 11 + # periodSeconds: 3 + # readinessProbe: + # httpGet: + # path: /api/v1/ehlo + # port: 8000 + # timeoutSeconds: 3 + ports: + - containerPort: 7085 + envFrom: + # - secretRef: + # name: api-creds + - configMapRef: + name: api-config + resources: + limits: + cpu: 50m + memory: 256Mi + requests: + cpu: 20m + memory: 128Mi + - apiVersion: v1 + kind: DeploymentConfig + metadata: + labels: + app: foi-request-form + role: web + name: web + spec: + strategy: + type: Rolling + triggers: + - type: ConfigChange + - type: ImageChange + imageChangeParams: + automatic: true + containerNames: + - web + from: + kind: ImageStreamTag + name: "web:${WEB_SOURCE_IMAGE_TAG}" + namespace: ${SOURCE_IMAGE_NAMESPACE} + replicas: ${{REPLICA_COUNT}} + selector: + app: foi-request-form + role: web + template: + metadata: + labels: + app: foi-request-form + role: web + name: foi-request-form + spec: + containers: + - name: web + image: " " + startupProbe: + httpGet: + path: / + port: 2015 + failureThreshold: 11 + periodSeconds: 3 + readinessProbe: + httpGet: + path: / + port: 2015 + timeoutSeconds: 3 + ports: + - containerPort: 2015 + # envFrom: + # - configMapRef: + # name: web-config + resources: + limits: + cpu: 50m + memory: 128Mi + requests: + cpu: 20m + memory: 64Mi + volumeMounts: + - name: config-vol + mountPath: /opt/app-root/etc/Caddyfile + subPath: Caddyfile + volumes: + - name: config-vol + configMap: + name: web-caddy-config +parameters: + - description: + The namespace of the OpenShift project containing the + imagestream for the application. + displayName: Environment namespace + name: NAMESPACE + required: true + - description: The openshift project where builds and target images are stored. + displayName: Build Project + name: SOURCE_IMAGE_NAMESPACE + required: true + - name: API_SOURCE_IMAGE_TAG + description: | + The name of the source image for the API component + displayName: API Source Image Tag + required: true + - name: WEB_SOURCE_IMAGE_TAG + description: | + The name of the source image for the Web component + displayName: Web Source Image Tag + required: true + - name: TLS_CERT_PEM + description: TLS certificate data in PEM format. + displayName: TLS Certificate + required: true + - name: TLS_KEY_PEM + description: | + TLS certificate private key data in PEM format. This will be in + the possesion of the person who created the Certificate Signing + Request (CSR). + displayName: TLS Private Key + required: true + - name: TLS_CACERT_PEM + description: | + TLS certificate cuthority certificate data in PEM format. If you + got your certificate from an iStore request, use L1KChain.txt. + displayName: TLS Certificate Authority Certificate + required: true + - name: HOSTNAME_HTTPS + description: Hostname serving the application + displayName: Route Name + required: true + - name: NODE_ENV + description: + requred: true + - name: REPLICA_COUNT + description: + requred: true + - name: FOI_REQUEST_API_PORT + description: + required: true + - name: FOI_REQUEST_SMTP + description: + required: true + - name: FOI_REQUEST_SMTP_PORT + description: + required: true + - name: FOI_REQUEST_SMTP_SECURE + description: + required: true + - name: FOI_REQUEST_INBOX + description: + required: true + - name: FOI_REQUEST_SENDER + description: + required: true + - name: FOI_KC_REALM + description: + required: true + - name: FOI_KC_URL + description: + required: true + - name: FOI_KC_CLIENTID + description: + required: true + - name: FOI_KC_SECRET + description: + required: true + - name: FOI_KC_SSL_REQUIRED + description: + required: true + - name: FOI_KC_PUBLIC_CLIENT + description: + required: true + - name: JWKS_URI + description: + required: true \ No newline at end of file From 273639631398458ccdda493942f49757465a7e5d Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 11:01:47 -0800 Subject: [PATCH 112/589] Update git ignore --- .gitignore | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index fb6c0450..049b9f81 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,11 @@ testem.log .DS_Store Thumbs.db +# OpenShift +*-secret.yaml +*-secret.json +*-secret.properties + # SSL *.pem *.key From 13e15ec393345c1a6992097b00bfaaf7bc68ac41 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 11:02:17 -0800 Subject: [PATCH 113/589] Add deployment properties --- openshift/dev.properties | 14 ++++++++++++++ openshift/prod.properties | 14 ++++++++++++++ openshift/test.properties | 14 ++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 openshift/dev.properties create mode 100644 openshift/prod.properties create mode 100644 openshift/test.properties diff --git a/openshift/dev.properties b/openshift/dev.properties new file mode 100644 index 00000000..0671a1e5 --- /dev/null +++ b/openshift/dev.properties @@ -0,0 +1,14 @@ +HOSTNAME_HTTPS=dev.foirequestform.gov.bc.ca +NODE_ENV=development +SOURCE_IMAGE_NAMESPACE=04d1a3-tools +API_SOURCE_IMAGE_TAG=latest +WEB_SOURCE_IMAGE_TAG=latest +REPLICA_COUNT=1 +FOI_REQUEST_API_PORT=7085 +FOI_REQUEST_SMTP=apps.smtp.gov.bc.ca +FOI_REQUEST_SMTP_PORT=25 +FOI_REQUEST_SMTP_SECURE=false +FOI_REQUEST_SENDER=donotreply@gov.bc.ca +FOI_KC_URL=https://dev.oidc.gov.bc.ca/auth +FOI_KC_SSL_REQUIRED=external +FOI_KC_PUBLIC_CLIENT=true diff --git a/openshift/prod.properties b/openshift/prod.properties new file mode 100644 index 00000000..90018717 --- /dev/null +++ b/openshift/prod.properties @@ -0,0 +1,14 @@ +HOSTNAME_HTTPS=foirequestform.gov.bc.ca +NODE_ENV=production +SOURCE_IMAGE_NAMESPACE=04d1a3-tools +API_SOURCE_IMAGE_TAG=prod +WEB_SOURCE_IMAGE_TAG=prod +REPLICA_COUNT=3 +FOI_REQUEST_API_PORT=7085 +FOI_REQUEST_SMTP=apps.smtp.gov.bc.ca +FOI_REQUEST_SMTP_PORT=25 +FOI_REQUEST_SMTP_SECURE=false +FOI_REQUEST_SENDER=donotreply@gov.bc.ca +FOI_KC_URL=https://oidc.gov.bc.ca/auth +FOI_KC_SSL_REQUIRED=external +FOI_KC_PUBLIC_CLIENT=true diff --git a/openshift/test.properties b/openshift/test.properties new file mode 100644 index 00000000..b3b95663 --- /dev/null +++ b/openshift/test.properties @@ -0,0 +1,14 @@ +HOSTNAME_HTTPS=test.foirequestform.gov.bc.ca +NODE_ENV=development +SOURCE_IMAGE_NAMESPACE=04d1a3-tools +API_SOURCE_IMAGE_TAG=test +WEB_SOURCE_IMAGE_TAG=test +REPLICA_COUNT=1 +FOI_REQUEST_API_PORT=7085 +FOI_REQUEST_SMTP=apps.smtp.gov.bc.ca +FOI_REQUEST_SMTP_PORT=25 +FOI_REQUEST_SMTP_SECURE=false +FOI_REQUEST_SENDER=donotreply@gov.bc.ca +FOI_KC_URL=https://test.oidc.gov.bc.ca/auth +FOI_KC_SSL_REQUIRED=external +FOI_KC_PUBLIC_CLIENT=true From 4539f846a9d1fcb3f61dbfd4372eb41e2c4fe42a Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 11:02:41 -0800 Subject: [PATCH 114/589] Add secret deployment manifest --- openshift/templates/deploy.yaml | 62 +++++++++++--------------------- openshift/templates/secrets.yaml | 55 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 41 deletions(-) create mode 100644 openshift/templates/secrets.yaml diff --git a/openshift/templates/deploy.yaml b/openshift/templates/deploy.yaml index 475cefe4..90697076 100644 --- a/openshift/templates/deploy.yaml +++ b/openshift/templates/deploy.yaml @@ -35,15 +35,10 @@ objects: FOI_REQUEST_SMTP: ${FOI_REQUEST_SMTP} FOI_REQUEST_SMTP_PORT: ${FOI_REQUEST_SMTP_PORT} FOI_REQUEST_SMTP_SECURE: ${FOI_REQUEST_SMTP_SECURE} - FOI_REQUEST_INBOX: ${FOI_REQUEST_INBOX} FOI_REQUEST_SENDER: ${FOI_REQUEST_SENDER} - FOI_KC_REALM: ${FOI_KC_REALM} FOI_KC_URL: ${FOI_KC_URL} - FOI_KC_CLIENTID: ${FOI_KC_CLIENTID} - FOI_KC_SECRET: ${FOI_KC_SECRET} FOI_KC_SSL_REQUIRED: ${FOI_KC_SSL_REQUIRED} FOI_KC_PUBLIC_CLIENT: ${FOI_KC_PUBLIC_CLIENT} - JWKS_URI: ${JWKS_URI} - apiVersion: v1 kind: ConfigMap metadata: @@ -58,12 +53,12 @@ objects: # Turn on the Web/file server file_server - templates { - mime "text/javascript" "application/javascript" - } + # templates { + # mime "text/javascript" "application/javascript" + # } # The site root - root * /opt/app-root/src/ + root * /opt/app-root/src # Because we should encode zstd gzip @@ -79,7 +74,7 @@ objects: #rewrite @try_files {http.matchers.file.relative} # This properly deals with react routes. - try_files {path} {path}/ /index.html + # try_files {path} {path}/ /index.html # On OCP we should log to stdout so Prometheus can # slurp up the logs for human consumption. @@ -152,10 +147,10 @@ objects: app: foi-request-form role: api ports: - - name: 8000-tcp - port: 8000 + - name: 7085-tcp + port: 7085 protocol: TCP - targetPort: 8000 + targetPort: 7085 - apiVersion: v1 kind: Service metadata: @@ -207,22 +202,22 @@ objects: containers: - name: api image: " " - # startupProbe: - # httpGet: - # path: /api/v1/ehlo - # port: 8000 - # failureThreshold: 11 - # periodSeconds: 3 - # readinessProbe: - # httpGet: - # path: /api/v1/ehlo - # port: 8000 - # timeoutSeconds: 3 + startupProbe: + httpGet: + path: /api/v1/configs + port: 7085 + failureThreshold: 10 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /api/v1/configs + port: 7085 + timeoutSeconds: 3 ports: - containerPort: 7085 envFrom: - # - secretRef: - # name: api-creds + - secretRef: + name: api-creds - configMapRef: name: api-config resources: @@ -358,30 +353,15 @@ parameters: - name: FOI_REQUEST_SMTP_SECURE description: required: true - - name: FOI_REQUEST_INBOX - description: - required: true - name: FOI_REQUEST_SENDER description: required: true - - name: FOI_KC_REALM - description: - required: true - name: FOI_KC_URL description: required: true - - name: FOI_KC_CLIENTID - description: - required: true - - name: FOI_KC_SECRET - description: - required: true - name: FOI_KC_SSL_REQUIRED description: required: true - name: FOI_KC_PUBLIC_CLIENT - description: - required: true - - name: JWKS_URI description: required: true \ No newline at end of file diff --git a/openshift/templates/secrets.yaml b/openshift/templates/secrets.yaml new file mode 100644 index 00000000..28ec5078 --- /dev/null +++ b/openshift/templates/secrets.yaml @@ -0,0 +1,55 @@ +# Copyright 2020 The Province of British Columbia +# +# Licensed 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. +# +--- +kind: Template +apiVersion: v1 +metadata: + name: api-creds + annotations: + description: RocktChat Reggie Secrets +parameters: + - name: FOI_KC_CLIENTID + displayName: FOI KC ClientID + description: The SSO client ID used by this application. + required: true + - name: FOI_KC_SECRET + displayName: FOI KC Secret + description: The SSO secret used by this particular client. + required: true + - name: FOI_REQUEST_INBOX + descripiton: The email address requests are sent to by the API. + displayName: FOI Request Inbox + required: true + - name: FOI_KC_REALM + displayName: FOI KC Realm + descripiton: The name of the SSO realm. + required: true + - name: JWKS_URI + display name: JWK URI + description: + required: true +objects: + - apiVersion: v1 + kind: Secret + metadata: + name: api-creds + labels: + app: foi-request-form + stringData: + FOI_KC_CLIENTID: ${FOI_KC_CLIENTID} + FOI_KC_SECRET: ${FOI_KC_SECRET} + FOI_REQUEST_INBOX: ${FOI_REQUEST_INBOX} + FOI_KC_REALM: ${FOI_KC_REALM} + JWKS_URI: ${JWKS_URI} From 4fd080f644b56a19554b88c2cb65530c1b5d743a Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 11:24:15 -0800 Subject: [PATCH 115/589] Work on workflow --- .github/workflows/web.yml | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index e4243253..d37d549b 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -1,12 +1,11 @@ -name: Test & Build +name: Test & Build Web on: push: paths: - "web/src/**/*.ts" - - "web/src/**/*.tsx" - - "web/package*.json" - - "web/public/**/*" - - "web/Caddyfile" + - "web/src/package*.json" + - "web/src/public/**/*" + workflow_dispatch: defaults: run: working-directory: ./web @@ -64,7 +63,24 @@ jobs: runs-on: ubuntu-latest needs: [test, build] steps: - - name: S2I Build + - name: Artifact Build + env: + NAMESPACE: 04d1a3-tools + BUILD_NAME: web-artifact-build + IMAGE_NAME: web-artifacts + uses: redhat-developer/openshift-actions@v1.1 + with: + version: "latest" + openshift_server_url: ${{ secrets.OpenShiftServerURL}} + parameters: '{"apitoken": "${{ secrets.OpenShiftToken }}", "acceptUntrustedCerts": "true"}' + cmd: | + 'version' + 'start-build ${BUILD_NAME} -n ${NAMESPACE} --follow' + - name: Image Build + env: + NAMESPACE: 04d1a3-tools + BUILD_NAME: web-image-build + IMAGE_NAME: web uses: redhat-developer/openshift-actions@v1.1 with: version: "latest" @@ -72,4 +88,4 @@ jobs: parameters: '{"apitoken": "${{ secrets.OpenShiftToken }}", "acceptUntrustedCerts": "true"}' cmd: | 'version' - 'start-build platsrv-registry-web-master-build --follow -n platform-registry-tools' + 'start-build ${BUILD_NAME} -n ${NAMESPACE} --follow' From 6b23e70a314e2d736a8412a1f08ec501de8762c5 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 11:28:49 -0800 Subject: [PATCH 116/589] Fix test options --- .github/workflows/web.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index d37d549b..9d1091a6 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -19,8 +19,8 @@ jobs: node-version: "12" - name: Install dependencies run: npm ci - - name: Unit tests w/ coverage - run: npm run test -- --coverage --passWithNoTests + - name: Unit tests + run: npm run test # - name: LINTing # run: npm run test:lint # - name: Upload coverage report From c9860e17a3e06d865f3d2586cc76a8fdd9965d62 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 11:33:47 -0800 Subject: [PATCH 117/589] Comment out test run --- .github/workflows/web.yml | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index 9d1091a6..f95b1a8d 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -10,28 +10,17 @@ defaults: run: working-directory: ./web jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@master - - uses: actions/setup-node@master - with: - node-version: "12" - - name: Install dependencies - run: npm ci - - name: Unit tests - run: npm run test - # - name: LINTing - # run: npm run test:lint - # - name: Upload coverage report - # env: - # CC_TEST_REPORTER_ID: ${{ secrets.TestReporterID }} - # CI: "true" - # run: | - # curl -Ls https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter - # chmod +x ./cc-test-reporter - # ./cc-test-reporter format-coverage -t lcov -o codeclimate.json - # ./cc-test-reporter upload-coverage -i codeclimate.json + # test: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@master + # - uses: actions/setup-node@master + # with: + # node-version: "12" + # - name: Install dependencies + # run: npm ci + # - name: Unit tests + # run: npm run test build: runs-on: ubuntu-latest needs: [test] From 45e54c66e0c94bc0165fb1852d6253f4917eb447 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 11:35:04 -0800 Subject: [PATCH 118/589] Fix workflow dependencies --- .github/workflows/web.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index f95b1a8d..f08810f9 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -23,7 +23,7 @@ jobs: # run: npm run test build: runs-on: ubuntu-latest - needs: [test] + # needs: [test] strategy: matrix: node-version: [10.x, 12.x] From 383432aeb075e915a324931253f04d17f35d631e Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 11:37:42 -0800 Subject: [PATCH 119/589] Fix dependencies --- .github/workflows/web.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index f08810f9..aeb298b1 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -50,7 +50,8 @@ jobs: s2i-build: if: github.event_name == 'push' && github.ref == 'refs/heads/master' runs-on: ubuntu-latest - needs: [test, build] + # needs: [test, build] + needs: [build] steps: - name: Artifact Build env: From faf2ebbb7ac6461e36fdeab9eae9c178e383ffda Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 11:43:49 -0800 Subject: [PATCH 120/589] Update node versions --- .github/workflows/web.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/web.yml b/.github/workflows/web.yml index aeb298b1..7a064ee4 100644 --- a/.github/workflows/web.yml +++ b/.github/workflows/web.yml @@ -26,7 +26,7 @@ jobs: # needs: [test] strategy: matrix: - node-version: [10.x, 12.x] + node-version: [10.x] steps: - uses: actions/checkout@v1 - uses: actions/setup-node@v1 From 7a784db7504085c2c71a3c5b9f51b894910b1c0a Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 11:53:30 -0800 Subject: [PATCH 121/589] Project organization --- Old_Jenkinsfile => cicd_old/Old_Jenkinsfile | 0 {s2i.old => cicd_old/s2i.old}/bin/assemble | 0 .../templates.old/angular-app/angular-app.json | 0 .../templates.old/angular-on-nginx/angular-on-nginx-build.json | 0 .../templates.old/angular-on-nginx/angular-on-nginx-deploy.json | 0 .../templates.old/angular-on-nginx/log-volume-create.json | 0 {openshift => cicd_old}/templates.old/nginx-runtime/Dockerfile | 0 .../templates.old/nginx-runtime/nginx-runtime.json | 0 .../templates.old/nginx-runtime/nginx.conf.template | 0 .../templates.old/nginx-runtime/s2i/bin/assemble | 0 .../templates.old/nginx-runtime/s2i/bin/assemble-runtime | 0 {openshift => cicd_old}/templates.old/nginx-runtime/s2i/bin/run | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename Old_Jenkinsfile => cicd_old/Old_Jenkinsfile (100%) rename {s2i.old => cicd_old/s2i.old}/bin/assemble (100%) rename {openshift => cicd_old}/templates.old/angular-app/angular-app.json (100%) rename {openshift => cicd_old}/templates.old/angular-on-nginx/angular-on-nginx-build.json (100%) rename {openshift => cicd_old}/templates.old/angular-on-nginx/angular-on-nginx-deploy.json (100%) rename {openshift => cicd_old}/templates.old/angular-on-nginx/log-volume-create.json (100%) rename {openshift => cicd_old}/templates.old/nginx-runtime/Dockerfile (100%) rename {openshift => cicd_old}/templates.old/nginx-runtime/nginx-runtime.json (100%) rename {openshift => cicd_old}/templates.old/nginx-runtime/nginx.conf.template (100%) rename {openshift => cicd_old}/templates.old/nginx-runtime/s2i/bin/assemble (100%) rename {openshift => cicd_old}/templates.old/nginx-runtime/s2i/bin/assemble-runtime (100%) rename {openshift => cicd_old}/templates.old/nginx-runtime/s2i/bin/run (100%) diff --git a/Old_Jenkinsfile b/cicd_old/Old_Jenkinsfile similarity index 100% rename from Old_Jenkinsfile rename to cicd_old/Old_Jenkinsfile diff --git a/s2i.old/bin/assemble b/cicd_old/s2i.old/bin/assemble similarity index 100% rename from s2i.old/bin/assemble rename to cicd_old/s2i.old/bin/assemble diff --git a/openshift/templates.old/angular-app/angular-app.json b/cicd_old/templates.old/angular-app/angular-app.json similarity index 100% rename from openshift/templates.old/angular-app/angular-app.json rename to cicd_old/templates.old/angular-app/angular-app.json diff --git a/openshift/templates.old/angular-on-nginx/angular-on-nginx-build.json b/cicd_old/templates.old/angular-on-nginx/angular-on-nginx-build.json similarity index 100% rename from openshift/templates.old/angular-on-nginx/angular-on-nginx-build.json rename to cicd_old/templates.old/angular-on-nginx/angular-on-nginx-build.json diff --git a/openshift/templates.old/angular-on-nginx/angular-on-nginx-deploy.json b/cicd_old/templates.old/angular-on-nginx/angular-on-nginx-deploy.json similarity index 100% rename from openshift/templates.old/angular-on-nginx/angular-on-nginx-deploy.json rename to cicd_old/templates.old/angular-on-nginx/angular-on-nginx-deploy.json diff --git a/openshift/templates.old/angular-on-nginx/log-volume-create.json b/cicd_old/templates.old/angular-on-nginx/log-volume-create.json similarity index 100% rename from openshift/templates.old/angular-on-nginx/log-volume-create.json rename to cicd_old/templates.old/angular-on-nginx/log-volume-create.json diff --git a/openshift/templates.old/nginx-runtime/Dockerfile b/cicd_old/templates.old/nginx-runtime/Dockerfile similarity index 100% rename from openshift/templates.old/nginx-runtime/Dockerfile rename to cicd_old/templates.old/nginx-runtime/Dockerfile diff --git a/openshift/templates.old/nginx-runtime/nginx-runtime.json b/cicd_old/templates.old/nginx-runtime/nginx-runtime.json similarity index 100% rename from openshift/templates.old/nginx-runtime/nginx-runtime.json rename to cicd_old/templates.old/nginx-runtime/nginx-runtime.json diff --git a/openshift/templates.old/nginx-runtime/nginx.conf.template b/cicd_old/templates.old/nginx-runtime/nginx.conf.template similarity index 100% rename from openshift/templates.old/nginx-runtime/nginx.conf.template rename to cicd_old/templates.old/nginx-runtime/nginx.conf.template diff --git a/openshift/templates.old/nginx-runtime/s2i/bin/assemble b/cicd_old/templates.old/nginx-runtime/s2i/bin/assemble similarity index 100% rename from openshift/templates.old/nginx-runtime/s2i/bin/assemble rename to cicd_old/templates.old/nginx-runtime/s2i/bin/assemble diff --git a/openshift/templates.old/nginx-runtime/s2i/bin/assemble-runtime b/cicd_old/templates.old/nginx-runtime/s2i/bin/assemble-runtime similarity index 100% rename from openshift/templates.old/nginx-runtime/s2i/bin/assemble-runtime rename to cicd_old/templates.old/nginx-runtime/s2i/bin/assemble-runtime diff --git a/openshift/templates.old/nginx-runtime/s2i/bin/run b/cicd_old/templates.old/nginx-runtime/s2i/bin/run similarity index 100% rename from openshift/templates.old/nginx-runtime/s2i/bin/run rename to cicd_old/templates.old/nginx-runtime/s2i/bin/run From 3fe19b684c786b149e56f54b4922fd8ea4b48eeb Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Mon, 8 Mar 2021 12:05:28 -0800 Subject: [PATCH 122/589] Add maintenance proxy --- openshift/templates/maintenance-proxy.yaml | 192 +++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 openshift/templates/maintenance-proxy.yaml diff --git a/openshift/templates/maintenance-proxy.yaml b/openshift/templates/maintenance-proxy.yaml new file mode 100644 index 00000000..3b533a67 --- /dev/null +++ b/openshift/templates/maintenance-proxy.yaml @@ -0,0 +1,192 @@ +# Copyright 2021 The Province of British Columbia +# +# Licensed 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. +# +--- +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + annotations: + description: | + Deployment template for the RocketChat reverse proxy. + name: ${NAME} +objects: + - apiVersion: v1 + kind: Route + metadata: + labels: + app: ${NAME} + name: ${NAME} + spec: + host: ${SOURCE_HOST_NAME} + port: + targetPort: 2015-tcp + tls: + termination: edge + to: + kind: Service + name: ${NAME} + weight: 100 + - apiVersion: v1 + kind: ConfigMap + metadata: + name: ${NAME}-config + labels: + app: ${NAME} + data: + Caddyfile: | + http://${SOURCE_HOST_NAME}:2015 { + redir https://${DESTINATION_HOST_NAME} 301 + respond /ehlo 200 + + log { + # errors stdout + output stdout + #format single_field common_log + level DEBUG + } + } + + :2015 { + respond /ehlo 200 + + log { + # errors stdout + output stdout + #format single_field common_log + level DEBUG + } + } + - apiVersion: v1 + kind: Service + metadata: + labels: + app: ${NAME} + name: ${NAME} + spec: + selector: + role: proxy + ports: + - name: 2015-tcp + port: 2015 + protocol: TCP + targetPort: 2015 + - apiVersion: v1 + kind: DeploymentConfig + metadata: + labels: + app: ${NAME} + name: ${NAME} + spec: + strategy: + type: Rolling + triggers: + - type: ConfigChange + replicas: ${{REPLICA_COUNT}} + selector: + role: proxy + template: + metadata: + labels: + app: ${NAME} + role: proxy + name: ${NAME} + spec: + containers: + - name: ${NAME} + imagePullPolicy: Always + image: "caddy:latest" + env: + - name: XDG_DATA_HOME + value: /tmp + startupProbe: + httpGet: + path: /ehlo + port: 2015 + scheme: HTTP + failureThreshold: 5 + periodSeconds: 3 + readinessProbe: + httpGet: + path: /ehlo + port: 2015 + timeoutSeconds: 10 + ports: + - containerPort: 2015 + resources: + limits: + cpu: 100m + memory: 92Mi + requests: + cpu: 30m + memory: 48Mi + volumeMounts: + - name: config-vol + mountPath: /etc/caddy/Caddyfile + subPath: Caddyfile + volumes: + - name: config-vol + configMap: + name: ${NAME}-config + imagePullSecrets: + - name: bcdevops-dockercfg + # - apiVersion: autoscaling/v1 + # kind: HorizontalPodAutoscaler + # metadata: + # labels: + # app: ${NAME} + # name: ${NAME} + # spec: + # scaleTargetRef: + # apiVersion: apps/v1 + # kind: DeploymentConfig + # name: ${NAME} + # minReplicas: ${{ROCKETCHAT_MIN_HPA}} + # maxReplicas: ${{ROCKETCHAT_MAX_HPA}} + # metrics: + # - type: Resource + # resource: + # name: cpu + # target: + # type: Utilization + # averageUtilization: 60 +parameters: + - description: + The name assigned to all of the objects defined in this template. You + should keep this as default unless your know what your doing. + displayName: Name + name: NAME + required: true + value: maintenance-proxy + - name: DESTINATION_HOST_NAME + description: + The destination address that is being proxied. + displayName: Redirect Destination + required: true + - name: SOURCE_HOST_NAME + description: | + The route that will be redirected to the destination URL. + displayName: Front Door Route + required: true + - name: REPLICA_COUNT + description: The number of PROXY pods to start + displayName: Replica Count + value: 3 + # - name: PROXY_MIN_HPA + # description: Min Number of PROXY pods for HPA + # displayName: PROXY Min HPA + # value: 3 + # - name: PROXY_MAX_HPA + # description: Max Number of PROXY pods for HPA + # displayName: PROXY Max HPA + # value: 9 \ No newline at end of file From 47b1879385b33c209fbb26d5b5ede122046c7d62 Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Tue, 23 Mar 2021 11:13:19 -0700 Subject: [PATCH 123/589] Fix type-o in ministry name --- web/src/app/MockClasses.ts | 2 +- web/src/app/services/data.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web/src/app/MockClasses.ts b/web/src/app/MockClasses.ts index 96be635b..a67c6068 100644 --- a/web/src/app/MockClasses.ts +++ b/web/src/app/MockClasses.ts @@ -71,7 +71,7 @@ export class MockDataService { getMinistries(): Observable { return of([ - { code: "AEST", name: "Advanced Education and Skills and Training" }, + { code: "AEST", name: "Advanced Education and Skills Training" }, { code: "AGRI", name: "Agriculture, Food, and Fisheries" }, { code: "AG", name: "Attorney General (and Minister Responsible for Housing)" }, { code: "PSSG", name: "Public Safety and Solicitor General" } diff --git a/web/src/app/services/data.json b/web/src/app/services/data.json index 8a01897d..b98aca1b 100644 --- a/web/src/app/services/data.json +++ b/web/src/app/services/data.json @@ -1,7 +1,7 @@ { "referenceData": { "ministries": [ - { "code": "AEST", "name": "Advanced Education and Skills and Training" }, + { "code": "AEST", "name": "Advanced Education and Skills Training" }, { "code": "AGRI", "name": "Agriculture, Food, and Fisheries" }, { "code": "AG", "name": "Attorney General (and Minister Responsible for Housing)" }, { "code": "PSA", "name": "BC Public Service Agency" }, From ef145f7ed608509ee8794ffffef273f37797876d Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Thu, 15 Apr 2021 13:48:50 -0700 Subject: [PATCH 124/589] Better handle routes --- openshift/templates/maintenance-proxy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openshift/templates/maintenance-proxy.yaml b/openshift/templates/maintenance-proxy.yaml index 3b533a67..09dee66f 100644 --- a/openshift/templates/maintenance-proxy.yaml +++ b/openshift/templates/maintenance-proxy.yaml @@ -46,7 +46,7 @@ objects: data: Caddyfile: | http://${SOURCE_HOST_NAME}:2015 { - redir https://${DESTINATION_HOST_NAME} 301 + redir https://${DESTINATION_HOST_NAME} permanent respond /ehlo 200 log { From b78f11113b042f866925237bce4f1e10c72801aa Mon Sep 17 00:00:00 2001 From: "Jason C. Leach" Date: Thu, 15 Apr 2021 13:52:30 -0700 Subject: [PATCH 125/589] Better deal with angular routes --- openshift/templates/deploy.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openshift/templates/deploy.yaml b/openshift/templates/deploy.yaml index 90697076..de9a5377 100644 --- a/openshift/templates/deploy.yaml +++ b/openshift/templates/deploy.yaml @@ -74,7 +74,7 @@ objects: #rewrite @try_files {http.matchers.file.relative} # This properly deals with react routes. - # try_files {path} {path}/ /index.html + try_files {path} {path}/ /index.html # On OCP we should log to stdout so Prometheus can # slurp up the logs for human consumption. From 0b2e3c637cb7523097897d4b06b4e0744c567fed Mon Sep 17 00:00:00 2001 From: Loren Mullane Date: Tue, 18 May 2021 10:34:28 -0700 Subject: [PATCH 126/589] Update issue templates Add issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 35 ++++++++++++++ .github/ISSUE_TEMPLATE/epic.md | 40 ++++++++++++++++ .github/ISSUE_TEMPLATE/task.md | 23 ++++++++++ .github/ISSUE_TEMPLATE/user-story.md | 68 ++++++++++++++++++++++++++++ 4 files changed, 166 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/epic.md create mode 100644 .github/ISSUE_TEMPLATE/task.md create mode 100644 .github/ISSUE_TEMPLATE/user-story.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..3a39825b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug in current situation** +A clear and concise description of what the bug is. + +**Link bug to the User Story** + +**Impact of this bug** +Describe the impact, i.e. what the impact is, and number of users impacted. + +**Chance of Occurring (high/medium/low/very low)** + +**Pre Conditions: which Env, any pre-requesites or assumptions to execute steps?** + +**Steps to Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Actual/ observed behaviour/ results** + +**Expected behaviour** +A clear and concise description of what you expected to happen. Use the gherking language. + +**Screenshots/ Visual Reference/ Source** +If applicable, add screenshots to help explain your problem. You an use screengrab. diff --git a/.github/ISSUE_TEMPLATE/epic.md b/.github/ISSUE_TEMPLATE/epic.md new file mode 100644 index 00000000..ad2b035f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/epic.md @@ -0,0 +1,40 @@ +--- +name: Epic +about: Consisting of many user stories, tasks and UX activities, an Epic captures + a large chunk of user needs +title: '' +labels: Epic +assignees: '' + +--- + +## Description: +- Short Description of the needed Epic in the below format + +* As a (who/ person) +* I want (what/ goal) +* so that (why/ benefit proposal) + + +* What are the most critical features being built as part of this Epic +* Expected Outcome – Justification why this Feature must be built, what is expected value and justification for priority. + +---- +**Sizing** + +* T-shirt size: + + [ ] S + [ ] M + [ ] L + [ ] XL + +(S=1-2 Sprints, M=2-3 Sprints, L=4-5 Sprints, XL=not sure, probably more than 5 Sprints). + +* *Risks and Assumptions** + +1. [ ] What are assumptions? +2. [ ] What are the risks? +3. [ ] Have we done an RFC on a technical approach? +4. [ ] Are the dependencies (technical, business, regulatory/policy) known? +5. [ ] Has work on this Epic been prioritized with key stakeholders? diff --git a/.github/ISSUE_TEMPLATE/task.md b/.github/ISSUE_TEMPLATE/task.md new file mode 100644 index 00000000..f0215b99 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/task.md @@ -0,0 +1,23 @@ +--- +name: Task +about: Capture tasks such as OCM, tech debt, UX , architecture and development +title: '' +labels: Task +assignees: '' + +--- + +Title of ticket: + +#### Description +Summarize issue + +#### Dependencies +Are there any dependencies? + +#### DOD +- [ ] List the items that need to be complete for this ticket to be considered done +- [ ] +- [ ] +- [ ] +- [ ] diff --git a/.github/ISSUE_TEMPLATE/user-story.md b/.github/ISSUE_TEMPLATE/user-story.md new file mode 100644 index 00000000..6601679e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/user-story.md @@ -0,0 +1,68 @@ +--- +name: User Story +about: User story capturing user needs. +title: '' +labels: Story +assignees: '' + +--- + +* As a (type of user) +* I want (goal) +* so that (reason/ why/ value) + +**Assumptions & Scope** +What are the assumptions for this story? + +What is in and not in scope? + +**Acceptance Criteria** + +**Scenario 1: xxxxxx** +* GIVEN ... (you or your condition) +* WHEN ... (what you do) +* THEN ... (what you see) + +**Scenario 2: xxxxxx** +* GIVEN ... (you or your condition) +* WHEN ... (what you do) +* THEN ... (what you see) + +**Scenario 3: xxxxxx** +... + +**Dependencies? What is the impact of this dependency? (If so, link dependency in the ticket, make it visible in a team´s backlog)** + + +**Validation Rules? (If yes, list here)** + +**Design** +@xxx - please link the Design here + +**Definition of Ready** + +1. [ ] Is there a well articulated User Story? +2. [ ] Is there Acceptance Criteria that covers all scenarios (happy/sad paths)? +3. [ ] If there is a user interface, is there a design? +4. [ ] Does the user story need user research/validation? +5. [ ] Does this User Story needs stakeholder approval? +6. [ ] Design / Solution accepted by Product Owner +7. [ ] Is this user story small enough to be completed in a Sprint? Should it be split? +8. [ ] Are the dependencies known/ understood? (technical, business, regulatory/policy) +9. [ ] Has the story been estimated? + +**Definition of Done** + +1. [ ] Passes developer unit tests +2. [ ] Passes peer code review +3. [ ] If there's a user interface, passes UX assurance +4. [ ] Passes QA of Acceptance Criteria with verification in Dev and Test +5. [ ] Confirm Test cases built and succeeding +6. [ ] No regression test failures +7. [ ] Test coverage acceptable by Product Owner +8. [ ] Ticket ready to be merged to master or story branch +9. [ ] Developer to list Config changes/ Update documents and designs +10. [ ] Can be demoed in Sprint Review +11. [ ] Tagged as part of a Release +12. [ ] Feature flagged if required +13. [ ] Change Management activities done? From d195e67824b9528c11ac1fc1b7007440f58f040e Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Mon, 7 Jun 2021 11:38:24 -0400 Subject: [PATCH 127/589] Merge API integration with Master branch copy --- api/apiCustomFunctions.js | 21 +++++++++++++++++++++ api/requestApiLayout.js | 27 +++++++++++++++++++++++++++ api/sample.env | 3 +++ openshift/dev.properties | 1 + openshift/prod.properties | 1 + openshift/test.properties | 1 + 6 files changed, 54 insertions(+) create mode 100644 api/requestApiLayout.js diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index 4cff69e4..bfbde28f 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -2,6 +2,7 @@ const fs = require('fs'); const EmailLayout = require('./emailLayout'); const restifyErrors = require('restify-errors'); +const { RequestAPI } = require('./requestApiLayout'); function submitFoiRequest(server, req, res, next) { const transomMailer = server.registry.get('transomSmtp'); @@ -11,6 +12,10 @@ function submitFoiRequest(server, req, res, next) { const MAX_ATTACH_MB = 5; const maxAttachBytes = MAX_ATTACH_MB * 1024 *1024; + const foiRequestAPIBackend = process.env.FOI_REQUEST_API_BACKEND; + const apiUrl = `${foiRequestAPIBackend}/foirawrequests`; + const requestAPI = new RequestAPI(); + req.params.requestData = JSON.parse(req.params.requestData); const data = { @@ -22,10 +27,18 @@ function submitFoiRequest(server, req, res, next) { const foiHtml = emailLayout.renderEmail(data.params,req.isAuthorised,req.userDetails); const foiAttachments = []; + const filesBase64 = []; if (req.files) { Object.keys(req.files).map(f => { const file = req.files[f]; if (file.size < maxAttachBytes) { + const filedata = fs.readFileSync(file.path, {encoding: 'base64'}); + + filesBase64.push({ + filename:file.name, + base64data:filedata + }); + foiAttachments.push({ filename: file.name, path: file.path @@ -63,6 +76,14 @@ function submitFoiRequest(server, req, res, next) { // }, 5000); } ); + //data.params["requestData"].Attachments = ["file.docx","TEST BASE64"]; + console.log("calling RAW FOI Request"); + if (req.files) { + data.params["requestData"].Attachments = filesBase64; + } + console.log(`data.params = ${JSON.stringify(data.params)}`); + const apiRespose = requestAPI.invokeRequestAPI(JSON.stringify(data.params), apiUrl); + console.log(`apiResponse = ${apiRespose}`); } module.exports = { submitFoiRequest }; diff --git a/api/requestApiLayout.js b/api/requestApiLayout.js new file mode 100644 index 00000000..2ef85c65 --- /dev/null +++ b/api/requestApiLayout.js @@ -0,0 +1,27 @@ +/** + * Keep the email layout functions together, outside of index.js + */ + 'use strict'; +const axios = require("axios"); + +function RequestAPI() { + + this.invokeRequestAPI = (data, apiUrl) => { + const axiosConfig = { + headers: { + 'Content-Type': 'application/json' + } + }; + axios.post(apiUrl, data, axiosConfig) + .then((response) => { + console.log(`axios response = ${response.status}`); + return response.status; + }) + .catch((error) => { + console.log(`axios error = ${error.message}`); + return error.message; + }); + }; + }; + + module.exports = { RequestAPI }; \ No newline at end of file diff --git a/api/sample.env b/api/sample.env index 5ba66e82..825c769a 100644 --- a/api/sample.env +++ b/api/sample.env @@ -6,6 +6,9 @@ FOI_REQUEST_UI="http://localhost:4200" FOI_REQUEST_API="http://localhost:7085" FOI_REQUEST_API_PORT="7085" +# Backend API +FOI_REQUEST_API_BACKEND="http://localhost:5000/api" + # If running MongoDB on localhost with with Auth # disabled, use the following to get the app running. # FOI_REQUEST_DB="mongodb://localhost/foi-request-db" diff --git a/openshift/dev.properties b/openshift/dev.properties index 0671a1e5..f49ad606 100644 --- a/openshift/dev.properties +++ b/openshift/dev.properties @@ -12,3 +12,4 @@ FOI_REQUEST_SENDER=donotreply@gov.bc.ca FOI_KC_URL=https://dev.oidc.gov.bc.ca/auth FOI_KC_SSL_REQUIRED=external FOI_KC_PUBLIC_CLIENT=true +FOI_REQUEST_API_BACKEND= diff --git a/openshift/prod.properties b/openshift/prod.properties index 90018717..0164e7ab 100644 --- a/openshift/prod.properties +++ b/openshift/prod.properties @@ -12,3 +12,4 @@ FOI_REQUEST_SENDER=donotreply@gov.bc.ca FOI_KC_URL=https://oidc.gov.bc.ca/auth FOI_KC_SSL_REQUIRED=external FOI_KC_PUBLIC_CLIENT=true +FOI_REQUEST_API_BACKEND= \ No newline at end of file diff --git a/openshift/test.properties b/openshift/test.properties index b3b95663..c0cf5a9a 100644 --- a/openshift/test.properties +++ b/openshift/test.properties @@ -12,3 +12,4 @@ FOI_REQUEST_SENDER=donotreply@gov.bc.ca FOI_KC_URL=https://test.oidc.gov.bc.ca/auth FOI_KC_SSL_REQUIRED=external FOI_KC_PUBLIC_CLIENT=true +FOI_REQUEST_API_BACKEND= \ No newline at end of file From 95cda7d5a096611eefe9d2aa36ae794c76faa9aa Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Mon, 7 Jun 2021 15:33:05 -0400 Subject: [PATCH 128/589] Updated api with error handling --- api/apiCustomFunctions.js | 96 +++++++++++++++++++++++++++---------- api/foiRequestApiService.js | 21 ++++++++ api/requestApiLayout.js | 27 ----------- 3 files changed, 91 insertions(+), 53 deletions(-) create mode 100644 api/foiRequestApiService.js delete mode 100644 api/requestApiLayout.js diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index bfbde28f..60fc415e 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -1,12 +1,17 @@ +/* Submit FOI Request + * 1. Save raw request data to DB + * 2. Send email with request details +*/ + 'use strict'; const fs = require('fs'); const EmailLayout = require('./emailLayout'); const restifyErrors = require('restify-errors'); -const { RequestAPI } = require('./requestApiLayout'); +const { RequestAPI } = require('./foiRequestApiService'); -function submitFoiRequest(server, req, res, next) { - const transomMailer = server.registry.get('transomSmtp'); - const emailLayout = new EmailLayout(); +const submitFoiRequest = async (server, req, res, next) => { + + const emailLayout = new EmailLayout(); const foiRequestInbox = process.env.FOI_REQUEST_INBOX; const MAX_ATTACH_MB = 5; @@ -23,22 +28,22 @@ function submitFoiRequest(server, req, res, next) { params: req.params, files: req.files }; - req.log.info(`Sending message to ${foiRequestInbox}`, data); - + req.log.info(`Sending message to ${foiRequestInbox}`, data); + const foiHtml = emailLayout.renderEmail(data.params,req.isAuthorised,req.userDetails); const foiAttachments = []; const filesBase64 = []; if (req.files) { Object.keys(req.files).map(f => { - const file = req.files[f]; - if (file.size < maxAttachBytes) { - const filedata = fs.readFileSync(file.path, {encoding: 'base64'}); + const file = req.files[f]; + if (file.size < maxAttachBytes) { + const filedata = fs.readFileSync(file.path, {encoding: 'base64'}); filesBase64.push({ filename:file.name, base64data:filedata }); - + foiAttachments.push({ filename: file.name, path: file.path @@ -50,7 +55,52 @@ function submitFoiRequest(server, req, res, next) { } }); } + + console.log("calling RAW FOI Request"); + if (req.files) { + data.params["requestData"].Attachments = filesBase64; + } + try { + const response = await requestAPI.invokeRequestAPI(JSON.stringify(data.params), apiUrl); + + console.log(`API response = ${response.status}`); + if(response.status === 200 && response.data.status) { + + var sentResponse = await sendEmail(foiHtml,foiAttachments); + + if(sentResponse.EmailSuccess) { + req.log.info('Success:', response.data.message); + res.send({ result: 'success' }); + next(); + } + else { + console.log(sentResponse.message); + const unavailable = new restifyErrors.ServiceUnavailableError(sentResponse.message || 'Service is unavailable.'); + return next(unavailable); + } + // req.log.info('Success:', response.data.message); + // res.send({ result: 'success' }); + // next(); + } + else { + req.log.info('Failed:', response); + const unavailable = new restifyErrors.ServiceUnavailableError('Service is unavailable.'); + return next(unavailable); + } + } + catch(error){ + console.log(`${error}`); + req.log.info('Failed:', error); + const unavailable = new restifyErrors.ServiceUnavailableError('Service is unavailable.'); + return next(unavailable); + } +} + +const sendEmail = async (foiHtml, foiAttachments) => { + var EmailSuccess = true; + var message = ""; + const transomMailer = server.registry.get('transomSmtp'); transomMailer.sendFromNoReply( { subject: 'New FOI Request', @@ -66,24 +116,18 @@ function submitFoiRequest(server, req, res, next) { // After files are deleted, process the result. // setTimeout(()=> { if (err) { + EmailSuccess = false; req.log.info('Failed:', err); - const unavailable = new restifyErrors.ServiceUnavailableError(err.message || 'Service is unavailable.'); - return next(unavailable); + message = err.message; } - req.log.info('Sent!', response); - res.send({ result: 'success' }); - next(); + else{ + EmailSuccess = true; + message = "Email Sent Successfully"; + req.log.info('EmailSent:', response); + } // }, 5000); - } - ); - //data.params["requestData"].Attachments = ["file.docx","TEST BASE64"]; - console.log("calling RAW FOI Request"); - if (req.files) { - data.params["requestData"].Attachments = filesBase64; - } - console.log(`data.params = ${JSON.stringify(data.params)}`); - const apiRespose = requestAPI.invokeRequestAPI(JSON.stringify(data.params), apiUrl); - console.log(`apiResponse = ${apiRespose}`); + }); + console.log(`bool : ${EmailSuccess}, errorMessage: ${errorMessage}`); + return { EmailSuccess, message }; } - module.exports = { submitFoiRequest }; diff --git a/api/foiRequestApiService.js b/api/foiRequestApiService.js new file mode 100644 index 00000000..173c7a41 --- /dev/null +++ b/api/foiRequestApiService.js @@ -0,0 +1,21 @@ +/* Request API integration + * FOI-Flow python API is getting invoked here + * Save raw request data to DB +*/ + +'use strict'; +const axios = require("axios"); + +function RequestAPI() { + + this.invokeRequestAPI = (data, apiUrl) => { + const axiosConfig = { + headers: { + 'Content-Type': 'application/json' + } + }; + return axios.post(apiUrl, data, axiosConfig); + + }; + }; + module.exports = { RequestAPI }; \ No newline at end of file diff --git a/api/requestApiLayout.js b/api/requestApiLayout.js deleted file mode 100644 index 2ef85c65..00000000 --- a/api/requestApiLayout.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Keep the email layout functions together, outside of index.js - */ - 'use strict'; -const axios = require("axios"); - -function RequestAPI() { - - this.invokeRequestAPI = (data, apiUrl) => { - const axiosConfig = { - headers: { - 'Content-Type': 'application/json' - } - }; - axios.post(apiUrl, data, axiosConfig) - .then((response) => { - console.log(`axios response = ${response.status}`); - return response.status; - }) - .catch((error) => { - console.log(`axios error = ${error.message}`); - return error.message; - }); - }; - }; - - module.exports = { RequestAPI }; \ No newline at end of file From be96d8db1a34ddea9a5a9104052f0f383013c214 Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Tue, 15 Jun 2021 13:41:42 -0400 Subject: [PATCH 129/589] Update package.json with axios --- api/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/api/package.json b/api/package.json index 17293d53..14b1dc17 100644 --- a/api/package.json +++ b/api/package.json @@ -21,6 +21,7 @@ "@transomjs/transom-server-functions": "^1.0.8", "@transomjs/transom-smtp": "^1.0.5", "arraybuffer-to-buffer": "0.0.5", + "axios": "^0.21.1", "bunyan-rotating-file-stream": "^1.6.3", "dotenv": "^6.2.0", "jsonwebtoken": "^8.5.0", From d71aca7b3c286bd9e00859b16f6e31cb8d5a1dd8 Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Tue, 15 Jun 2021 16:37:21 -0400 Subject: [PATCH 130/589] Bug fixing of server variable in sendEmail --- api/apiCustomFunctions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index 60fc415e..552d7ae0 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -67,7 +67,7 @@ const submitFoiRequest = async (server, req, res, next) => { console.log(`API response = ${response.status}`); if(response.status === 200 && response.data.status) { - var sentResponse = await sendEmail(foiHtml,foiAttachments); + var sentResponse = await sendEmail(foiHtml, foiAttachments, server); if(sentResponse.EmailSuccess) { req.log.info('Success:', response.data.message); @@ -97,7 +97,7 @@ const submitFoiRequest = async (server, req, res, next) => { } } -const sendEmail = async (foiHtml, foiAttachments) => { +const sendEmail = async (foiHtml, foiAttachments, server) => { var EmailSuccess = true; var message = ""; const transomMailer = server.registry.get('transomSmtp'); From 5c974e845c7487d81034e2f780dde7bf0ec09626 Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Tue, 15 Jun 2021 16:46:54 -0400 Subject: [PATCH 131/589] sendEmail parameter added: foiRequestInbox --- api/apiCustomFunctions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index 552d7ae0..afa535b8 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -67,7 +67,7 @@ const submitFoiRequest = async (server, req, res, next) => { console.log(`API response = ${response.status}`); if(response.status === 200 && response.data.status) { - var sentResponse = await sendEmail(foiHtml, foiAttachments, server); + var sentResponse = await sendEmail(foiRequestInbox, foiHtml, foiAttachments, server); if(sentResponse.EmailSuccess) { req.log.info('Success:', response.data.message); @@ -97,7 +97,7 @@ const submitFoiRequest = async (server, req, res, next) => { } } -const sendEmail = async (foiHtml, foiAttachments, server) => { +const sendEmail = async (foiRequestInbox, foiHtml, foiAttachments, server) => { var EmailSuccess = true; var message = ""; const transomMailer = server.registry.get('transomSmtp'); From 47cfcaf03a15e0ac557b0c76f97ff381d65e09cf Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Tue, 15 Jun 2021 16:59:53 -0400 Subject: [PATCH 132/589] BugFix: sendEmail reference error --- api/apiCustomFunctions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index afa535b8..62df5a8b 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -127,7 +127,7 @@ const sendEmail = async (foiRequestInbox, foiHtml, foiAttachments, server) => { } // }, 5000); }); - console.log(`bool : ${EmailSuccess}, errorMessage: ${errorMessage}`); + console.log(`Sent Email? : ${EmailSuccess}, Message: ${message}`); return { EmailSuccess, message }; } module.exports = { submitFoiRequest }; From 73f2a4dbc796401d04644e401a06091d189a699b Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Tue, 15 Jun 2021 17:07:02 -0400 Subject: [PATCH 133/589] removed unnecessary logs --- api/apiCaptcha.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/apiCaptcha.js b/api/apiCaptcha.js index 91ba37f4..4b32e186 100644 --- a/api/apiCaptcha.js +++ b/api/apiCaptcha.js @@ -230,7 +230,7 @@ function captchaInit(options) { console.log('Request is already validated'+req.userDetails.firstName); return next(); } - console.log('req.verified ',req.verified ) + var token = req.headers[CAPTCHA_TOKEN_HEADER.toLowerCase()] || ''; token = token.replace('Bearer ', ''); var nonce = req.headers[CAPTCHA_NONCE_HEADER]; From bbb7088c6e19a87a44e5a9a639325977c14c94fd Mon Sep 17 00:00:00 2001 From: Adam Coard Date: Wed, 7 Jul 2021 14:00:56 -0700 Subject: [PATCH 134/589] Add logging to API request to see failure --- api/apiCustomFunctions.js | 1 + 1 file changed, 1 insertion(+) diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index 62df5a8b..0f1c237e 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -62,6 +62,7 @@ const submitFoiRequest = async (server, req, res, next) => { } try { + console.log('Before apiUrl request', {apiUrl, data: data.params}) const response = await requestAPI.invokeRequestAPI(JSON.stringify(data.params), apiUrl); console.log(`API response = ${response.status}`); From a5aef27c7c5dc7715b5ebda795ab44a6d4559ca1 Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Tue, 20 Jul 2021 19:40:28 -0400 Subject: [PATCH 135/589] #207 - Ministry code updated, Added unit test for API integration --- api/test/foiRequestApiService.spec.js | 117 ++++++++++++++++++++++++++ web/src/app/MockClasses.ts | 2 +- web/src/app/services/data.json | 10 +-- 3 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 api/test/foiRequestApiService.spec.js diff --git a/api/test/foiRequestApiService.spec.js b/api/test/foiRequestApiService.spec.js new file mode 100644 index 00000000..33a649c8 --- /dev/null +++ b/api/test/foiRequestApiService.spec.js @@ -0,0 +1,117 @@ +'use strict'; +const sinon = require('sinon'); +const RequestAPI = require('../foiRequestApiService'); +const chai = require('chai'); +const chaiAsPromised = require('chai-as-promised'); + +chai.use(require('chai-string')); +chai.use(chaiAsPromised); +const expect = chai.expect; + +describe('requestAPIervice', () => { + beforeEach( () => { + requestAPIService = new RequestAPI(); + stub = sinon.stub(axios, "post"); + foiRequestAPIBackend = process.env.FOI_REQUEST_API_BACKEND; + apiUrl = `${foiRequestAPIBackend}/foirawrequests`; + sampleRequestData = { + requestType: { + requestType: 'personal' + }, + selectAbout: { + yourself: true, + child: null, + another: null + }, + ministry: { + defaultMinistry: { + code: 'MCF', + name: 'Children and Family Development' + }, + selectedMinistry: [ + { + code: 'MCF', + name: 'Children and Family Development', + defaulted: true, + selected: true + } + ], + ministryPage: '/personal/ministry-confirmation' + }, + contactInfo: { + firstName: 'Colin', + middleName: 'Jack', + lastName: 'Westfall', + birthDate: timezoneAdjust('2019-02-28T00:00:00.000Z'), + alsoKnownAs: 'The Shuffler', + businessName: "Province of B.C., Ministry of Citizens' Services" + }, + anotherInformation: { + firstName: 'Colin', + middleName: 'Jack', + lastName: 'Westfall', + dateOfBirth: timezoneAdjust('2010-09-22T00:00:00.000Z'), + alsoKnownAs: 'Mr. McGoo' + }, + childInformation: { + firstName: 'Johnny', + middleName: 'Bobbert', + lastName: 'Driscol', + dateOfBirth: timezoneAdjust('2007-05-26T00:00:00.000Z'), + alsoKnownAs: 'Little Johnny Driscol' + }, + requestTopic: { + value: 'adoption', + text: 'Adoption', + ministryCode: 'MCF' + }, + descriptionTimeframe: { + description: 'Foosball tables', + fromDate: timezoneAdjust('2019-03-21T00:00:00.000Z'), + toDate: timezoneAdjust('2019-03-28T00:00:00.000Z'), + correctionalServiceNumber: 'Corr-654321', + publicServiceEmployeeNumber: 'Pub-456789', + topic: 'Adoption' + }, + adoptiveParents: { + motherFirstName: 'Marge', + motherLastName: 'Westfall', + fatherFirstName: 'Homer', + fatherLastName: 'Westfall' + }, + contactInfoOptions: { + phonePrimary: '7785550628', + phoneSecondary: '+1 077865552824', + email: 'homer@springfield.com', + address: '108-2260 Maple Ave N.', + city: 'Sooke', + postal: 'V9Z 1L2', + province: 'British Columbia', + country: 'Canada' + }, + Attachments: [] + }; + }); + afterEach(() => { + stub.restore(); + }); + + it('should exist and have the expected functions', () => { + expect(requestAPIService).to.exist; + const fx = ['invokeRequestAPI']; + fx.map(fxName => { + expect(requestAPIService[fxName]).to.exist; + }); + expect(Object.keys(requestAPIService).length).to.equal(1); + }); + + it("should send request with correct parameters", () => { + + requestAPIService.invokeRequestAPI(sampleRequestData, apiUrl); + expect( + stub.calledWith(apiUrl, { + params: sampleRequestData + }) + ).to.be.true; + }); +}); \ No newline at end of file diff --git a/web/src/app/MockClasses.ts b/web/src/app/MockClasses.ts index a67c6068..3464d01f 100644 --- a/web/src/app/MockClasses.ts +++ b/web/src/app/MockClasses.ts @@ -72,7 +72,7 @@ export class MockDataService { getMinistries(): Observable { return of([ { code: "AEST", name: "Advanced Education and Skills Training" }, - { code: "AGRI", name: "Agriculture, Food, and Fisheries" }, + { code: "AFF", name: "Agriculture, Food, and Fisheries" }, { code: "AG", name: "Attorney General (and Minister Responsible for Housing)" }, { code: "PSSG", name: "Public Safety and Solicitor General" } ]); diff --git a/web/src/app/services/data.json b/web/src/app/services/data.json index b98aca1b..0632a56f 100644 --- a/web/src/app/services/data.json +++ b/web/src/app/services/data.json @@ -2,14 +2,14 @@ "referenceData": { "ministries": [ { "code": "AEST", "name": "Advanced Education and Skills Training" }, - { "code": "AGRI", "name": "Agriculture, Food, and Fisheries" }, + { "code": "AFF", "name": "Agriculture, Food, and Fisheries" }, { "code": "AG", "name": "Attorney General (and Minister Responsible for Housing)" }, { "code": "PSA", "name": "BC Public Service Agency" }, { "code": "MCF", "name": "Children and Family Development" }, { "code": "CITZ", "name": "Citizens’ Services" }, { "code": "EDUC", "name": "Education" }, { "code": "EMBC", "name": "Emergency Management BC" }, - { "code": "EMPR", "name": "Energy, Mines and Low Carbon Innovation (and Minister Responsible for the Consular Corps of British Columbia)" }, + { "code": "EMLI", "name": "Energy, Mines and Low Carbon Innovation (and Minister Responsible for the Consular Corps of British Columbia)" }, { "code": "ENV", "name": "Environment and Climate Change Strategy (and Minister Responsible for Translink)" }, { "code": "EAO", "name": "Environmental Assessment Office" }, { "code": "FIN", "name": "Finance" }, @@ -23,14 +23,14 @@ }, { "code": "HLTH", "name": "Health (and Minister Responsible for Francophone Affairs)" }, { "code": "IRR", "name": "Indigenous Relations and Reconciliation" }, - { "code": "JTT", "name": "Jobs, Economic Recovery and Innovation" }, + { "code": "JERI", "name": "Jobs, Economic Recovery and Innovation" }, { "code": "LBR", "name": "Labour" }, { "code": "MMHA", "name": "Mental Health and Addictions" }, - { "code": "MAH", "name": "Municipal Affairs" }, + { "code": "MUNI", "name": "Municipal Affairs" }, { "code": "PREM", "name": "Office of the Premier" }, { "code": "PSSG", "name": "Public Safety and Solicitor General" }, { "code": "SDPR", "name": "Social Development and Poverty Reduction" }, - { "code": "TAC", "name": "Tourism, Arts, Culture and Sport" }, + { "code": "TACS", "name": "Tourism, Arts, Culture and Sport" }, { "code": "TRAN", "name": "Transportation and Infrastructure" } ], "topicYourself": [ From 9f2ebe63c706f13812370e06eeab9dee73b87e69 Mon Sep 17 00:00:00 2001 From: divyav-aot Date: Tue, 20 Jul 2021 19:45:02 -0400 Subject: [PATCH 136/589] #208 - corrected the taskid from 207 to 208 --- web/src/app/services/data.json | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/web/src/app/services/data.json b/web/src/app/services/data.json index 0632a56f..d363a3a0 100644 --- a/web/src/app/services/data.json +++ b/web/src/app/services/data.json @@ -13,14 +13,8 @@ { "code": "ENV", "name": "Environment and Climate Change Strategy (and Minister Responsible for Translink)" }, { "code": "EAO", "name": "Environmental Assessment Office" }, { "code": "FIN", "name": "Finance" }, - { - "code": "FLNR", - "name": "Forests, Lands, Natural Resource Operations and Rural Development" - }, - { - "code": "GCPE", - "name": "Government Communications and Public Engagement" - }, + { "code": "FLNR", "name": "Forests, Lands, Natural Resource Operations and Rural Development" }, + { "code": "GCPE", "name": "Government Communications and Public Engagement" }, { "code": "HLTH", "name": "Health (and Minister Responsible for Francophone Affairs)" }, { "code": "IRR", "name": "Indigenous Relations and Reconciliation" }, { "code": "JERI", "name": "Jobs, Economic Recovery and Innovation" }, From e70db6505f3bac3d92c3eb6299c92d7b8fe5b769 Mon Sep 17 00:00:00 2001 From: Jad Date: Thu, 14 Oct 2021 14:24:05 -0700 Subject: [PATCH 137/589] FOI Web UI flow change after submission --- api/apiCustomFunctions.js | 49 +++++++++++++++++++ web/src/app/app-routing.module.ts | 3 +- .../progress-bar/progress-bar.component.ts | 3 +- .../payment/payment.component.html | 25 ++++++++++ .../payment/payment.component.scss | 9 ++++ .../payment/payment.component.spec.ts | 25 ++++++++++ .../payment/payment.component.ts | 48 ++++++++++++++++++ .../review-submit/review-submit.component.ts | 4 ++ .../route-components.module.ts | 4 +- web/src/app/services/data.json | 4 +- web/src/app/services/data.service.ts | 5 ++ web/src/app/transom-api-client.service.ts | 11 +++++ 12 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 web/src/app/route-components/payment/payment.component.html create mode 100644 web/src/app/route-components/payment/payment.component.scss create mode 100644 web/src/app/route-components/payment/payment.component.spec.ts create mode 100644 web/src/app/route-components/payment/payment.component.ts diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index 4cff69e4..6e9a8953 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -12,6 +12,7 @@ function submitFoiRequest(server, req, res, next) { const maxAttachBytes = MAX_ATTACH_MB * 1024 *1024; req.params.requestData = JSON.parse(req.params.requestData); + const needsPayment = req.params.requestData.requestType?.requestType === 'general' const data = { envMessage: process.env.NODE_ENV, @@ -37,7 +38,55 @@ function submitFoiRequest(server, req, res, next) { } }); } + + console.log("calling RAW FOI Request"); + if (req.files) { + data.params["requestData"].Attachments = filesBase64; + } + try { + const response = await requestAPI.invokeRequestAPI(JSON.stringify(data.params), apiUrl); + + console.log(`API response = ${response.status}`); + if(response.status === 200 && response.data.status ) { + + // if request needs payment, return earlier to prevent sending email as it will be sent after payment. + if(needsPayment) { + req.log.info('Success:', response.data.message); + res.send({ result: 'success', id: response.data.id }); + return next(); + } + + const sentResponse = await sendEmail(foiHtml,foiAttachments); + + if(sentResponse.EmailSuccess) { + req.log.info('Success:', response.data.message); + res.send({ result: 'success', id: response.data.id }); + next(); + } + else { + console.log(sentResponse.message); + const unavailable = new restifyErrors.ServiceUnavailableError(sentResponse.message || 'Service is unavailable.'); + return next(unavailable); + } + } + else { + req.log.info('Failed:', response); + const unavailable = new restifyErrors.ServiceUnavailableError('Service is unavailable.'); + return next(unavailable); + } + } + catch(error){ + console.log(`${error}`); + req.log.info('Failed:', error); + const unavailable = new restifyErrors.ServiceUnavailableError('Service is unavailable.'); + return next(unavailable); + } +} +const sendEmail = async (foiHtml, foiAttachments) => { + var EmailSuccess = true; + var message = ""; + const transomMailer = server.registry.get('transomSmtp'); transomMailer.sendFromNoReply( { subject: 'New FOI Request', diff --git a/web/src/app/app-routing.module.ts b/web/src/app/app-routing.module.ts index 984bff5e..0d82e2a0 100644 --- a/web/src/app/app-routing.module.ts +++ b/web/src/app/app-routing.module.ts @@ -20,7 +20,7 @@ import { RequestTopicComponent } from './route-components/request-topic/request- import { ReviewSubmitCompleteComponent } from './route-components/review-submit-complete/review-submit-complete.component'; import { AdoptiveParentsComponent } from './route-components/adoptive-parents/adoptive-parents.component'; import { SigninComponent } from './route-components/signin/signin.component'; - +import { PaymentComponent } from './route-components/payment/payment.component'; const routes: Routes = [ { path: '', component: LandingComponent }, @@ -38,6 +38,7 @@ const routes: Routes = [ { path: 'general/contact-info-options', component: ContactInfoOptionsComponent }, { path: 'general/review-submit', component: ReviewSubmitComponent }, { path: 'general/submit-complete', component: ReviewSubmitCompleteComponent}, + { path: 'general/payment', component: PaymentComponent}, // Personal { path: 'personal/select-about', component: SelectAboutComponent }, diff --git a/web/src/app/progress-bar/progress-bar.component.ts b/web/src/app/progress-bar/progress-bar.component.ts index 13aa4733..8b131fc8 100644 --- a/web/src/app/progress-bar/progress-bar.component.ts +++ b/web/src/app/progress-bar/progress-bar.component.ts @@ -13,7 +13,8 @@ export class ProgressBarComponent implements OnInit { progressBarList: any[] = [{"route":"Getting Started", "progress": 1}, {"route":"Your Request", "progress": 2}, {"route":"Contact Info", "progress": 3}, - {"route":"Review & Submit", "progress": 4} + {"route":"Review & Submit", "progress": 4}, + {"route":"Payment", "progress": 5} ]; @Input() public currentProgress: number = 0; diff --git a/web/src/app/route-components/payment/payment.component.html b/web/src/app/route-components/payment/payment.component.html new file mode 100644 index 00000000..2dc68a83 --- /dev/null +++ b/web/src/app/route-components/payment/payment.component.html @@ -0,0 +1,25 @@ + +
    +

    Fee details

    +

    + This basic fee is calculated based on your selections +

    +

    + We have calculated that the basic fee of this application is: ${{fee}} +

    + +
    + + +
    + +
    + +
    diff --git a/web/src/app/route-components/payment/payment.component.scss b/web/src/app/route-components/payment/payment.component.scss new file mode 100644 index 00000000..67b3a09d --- /dev/null +++ b/web/src/app/route-components/payment/payment.component.scss @@ -0,0 +1,9 @@ +@import '../../styles/variables.scss'; + +.buttonbar { + margin: 2rem 0 2rem 0; +} + +.buttonbar button { + margin-right: 10px; +} \ No newline at end of file diff --git a/web/src/app/route-components/payment/payment.component.spec.ts b/web/src/app/route-components/payment/payment.component.spec.ts new file mode 100644 index 00000000..4b19cd1d --- /dev/null +++ b/web/src/app/route-components/payment/payment.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PaymentComponent } from './payment.component'; + +describe('PaymentComponent', () => { + let component: PaymentComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PaymentComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PaymentComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/web/src/app/route-components/payment/payment.component.ts b/web/src/app/route-components/payment/payment.component.ts new file mode 100644 index 00000000..96f271d3 --- /dev/null +++ b/web/src/app/route-components/payment/payment.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { DataService } from 'src/app/services/data.service'; +import { BaseComponent } from 'src/app/utils-components/base/base.component'; +import { FoiRequest } from 'src/app/models/FoiRequest'; + +@Component({ + selector: 'app-payment', + templateUrl: './payment.component.html', + styleUrls: ['./payment.component.scss'] +}) +export class PaymentComponent implements OnInit { + @ViewChild(BaseComponent) base: BaseComponent; + fee= null; + foiRequest: FoiRequest; + feeCode = 'FOI010' + isBusy = true; + + ministryKey = "ministry" + + constructor(private dataService: DataService) { } + + ngOnInit() { + this.foiRequest = this.dataService.getCurrentState(); + + const feeDetails = { + selectedMinistry: this.foiRequest.requestData[this.ministryKey].ministry + } + + this.dataService.getFeeDetails(this.feeCode, feeDetails).subscribe(result => { + this.fee = result.fee; + this.isBusy = false; + }, error => { + this.isBusy = false; + console.log('Submission failed: ', error); + alert('Temporary unable to fetch fee details. Please try again in a few minutes.'); + this.base.goFoiBack(); + }) + } + + doGoBack() { + this.dataService.setCurrentState(this.foiRequest); + this.base.goFoiBack(); + } + + doContinue() { + + } +} diff --git a/web/src/app/route-components/review-submit/review-submit.component.ts b/web/src/app/route-components/review-submit/review-submit.component.ts index 23514f91..8c565c86 100644 --- a/web/src/app/route-components/review-submit/review-submit.component.ts +++ b/web/src/app/route-components/review-submit/review-submit.component.ts @@ -60,6 +60,10 @@ export class ReviewSubmitComponent implements OnInit { doContinue() { this.isBusy = true; this.dataService.submitRequest(this.authToken, this.captchaNonce, this.foiRequest).subscribe(result => { + + this.foiRequest.requestData.requestId = result.id; + this.dataService.setCurrentState(this.foiRequest); + this.isBusy = false; // If the user is authenticated, logout the user if(this.keycloakService.isAuthenticated()) { diff --git a/web/src/app/route-components/route-components.module.ts b/web/src/app/route-components/route-components.module.ts index 27636233..588ad204 100644 --- a/web/src/app/route-components/route-components.module.ts +++ b/web/src/app/route-components/route-components.module.ts @@ -28,6 +28,7 @@ import { OwlDateTimeModule, OwlNativeDateTimeModule } from 'ng-pick-datetime'; import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { library } from '@fortawesome/fontawesome-svg-core'; import { faSpinner } from '@fortawesome/free-solid-svg-icons'; +import { PaymentComponent } from './payment/payment.component'; // Add an icon to the library for convenient access in other components library.add(faSpinner); @@ -55,7 +56,8 @@ library.add(faSpinner); ChildInformationComponent, VerifyYourIdentityComponent, AnotherInformationComponent, - AdoptiveParentsComponent + AdoptiveParentsComponent, + PaymentComponent, ], imports: [ // Required to use these in children of RouteComponentsModule diff --git a/web/src/app/services/data.json b/web/src/app/services/data.json index b98aca1b..be4c444a 100644 --- a/web/src/app/services/data.json +++ b/web/src/app/services/data.json @@ -125,7 +125,9 @@ { "route": "general/contact-info", "progress": 3 }, { "route": "general/contact-info-options", "progress": 3 }, { "route": "general/review-submit", "progress": 4 }, - { "route": "general/submit-complete", "progress": 4 } + { "route": "general/payment", "progress": 5 }, + { "route": "general/payment-complete", "progress": 6 }, + { "route": "general/submit-complete", "progress": 7 } ] }, "personal": { diff --git a/web/src/app/services/data.service.ts b/web/src/app/services/data.service.ts index 904ac81b..6b323f71 100644 --- a/web/src/app/services/data.service.ts +++ b/web/src/app/services/data.service.ts @@ -242,6 +242,11 @@ export class DataService { return this.apiClient.postFoiRequest(foiRequest); } + getFeeDetails(feeCode: String, details?: Object): Observable { + + return this.apiClient.getFeeDetails(feeCode, details); + } + /** * Create a flattened copy of the routes defined in data.json. * This makes it simpler to derermine what are the diff --git a/web/src/app/transom-api-client.service.ts b/web/src/app/transom-api-client.service.ts index 773e96fb..c3701e19 100644 --- a/web/src/app/transom-api-client.service.ts +++ b/web/src/app/transom-api-client.service.ts @@ -23,11 +23,13 @@ import { FoiRequest, BlobFile } from "./models/FoiRequest"; }) export class TransomApiClientService { public baseUrl: string; + public requestManagementUrl: string private headers: any; public currentUser: User; constructor(public http: HttpClient, private storage: LocalStorageService) { this.baseUrl = "/api/v1"; + this.requestManagementUrl = ""; this.headers = {}; } @@ -99,4 +101,13 @@ export class TransomApiClientService { }); return this.handleResponse(obs); } + + getFeeDetails(feeCode: String, details?: Object): Observable { + const url = this.requestManagementUrl + `/payments/${feeCode}` + + const obs = this.http.post(url, JSON.stringify(details), { + headers: this.headers + }); + return this.handleResponse(obs); + } } From 3020a059f8bc21ba5696f29504e47fc2f2d54456 Mon Sep 17 00:00:00 2001 From: Jad Date: Thu, 14 Oct 2021 14:38:00 -0700 Subject: [PATCH 138/589] Fix progress numbers for correct progress bar display --- web/src/app/progress-bar/progress-bar.component.ts | 3 ++- web/src/app/services/data.json | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/web/src/app/progress-bar/progress-bar.component.ts b/web/src/app/progress-bar/progress-bar.component.ts index 8b131fc8..a192ce6a 100644 --- a/web/src/app/progress-bar/progress-bar.component.ts +++ b/web/src/app/progress-bar/progress-bar.component.ts @@ -14,7 +14,8 @@ export class ProgressBarComponent implements OnInit { {"route":"Your Request", "progress": 2}, {"route":"Contact Info", "progress": 3}, {"route":"Review & Submit", "progress": 4}, - {"route":"Payment", "progress": 5} + {"route":"Payment", "progress": 5}, + {"route":"Complete", "progress": 6} ]; @Input() public currentProgress: number = 0; diff --git a/web/src/app/services/data.json b/web/src/app/services/data.json index be4c444a..aed6331e 100644 --- a/web/src/app/services/data.json +++ b/web/src/app/services/data.json @@ -126,8 +126,8 @@ { "route": "general/contact-info-options", "progress": 3 }, { "route": "general/review-submit", "progress": 4 }, { "route": "general/payment", "progress": 5 }, - { "route": "general/payment-complete", "progress": 6 }, - { "route": "general/submit-complete", "progress": 7 } + { "route": "general/payment-complete", "progress": 5 }, + { "route": "general/submit-complete", "progress": 6 } ] }, "personal": { @@ -164,7 +164,7 @@ "progress": 3 }, { "route": "personal/review-submit", "progress": 4 }, - { "route": "personal/submit-complete", "progress": 4 } + { "route": "personal/submit-complete", "progress": 6 } ] }, "child": { From a9ee4caaeba4e6ae10c596cf8283d714cb3a2eb9 Mon Sep 17 00:00:00 2001 From: Jad Date: Thu, 14 Oct 2021 18:46:13 -0700 Subject: [PATCH 139/589] FOI-WEB : Calculate fees --- web/src/app/models/FeeRequestDetails.ts | 3 ++ .../payment/payment.component.ts | 6 ++-- web/src/app/services/data.service.ts | 34 +++++++++++++++++-- web/src/app/transom-api-client.service.ts | 8 ++--- web/src/proxy.conf.json | 7 +++- 5 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 web/src/app/models/FeeRequestDetails.ts diff --git a/web/src/app/models/FeeRequestDetails.ts b/web/src/app/models/FeeRequestDetails.ts new file mode 100644 index 00000000..3ada92c6 --- /dev/null +++ b/web/src/app/models/FeeRequestDetails.ts @@ -0,0 +1,3 @@ +export interface FeeRequestDetails { + selectedMinistry?: [Object] + } \ No newline at end of file diff --git a/web/src/app/route-components/payment/payment.component.ts b/web/src/app/route-components/payment/payment.component.ts index 96f271d3..b67a6691 100644 --- a/web/src/app/route-components/payment/payment.component.ts +++ b/web/src/app/route-components/payment/payment.component.ts @@ -2,6 +2,7 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { DataService } from 'src/app/services/data.service'; import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { FoiRequest } from 'src/app/models/FoiRequest'; +import { FeeRequestDetails } from 'src/app/models/FeeRequestDetails'; @Component({ selector: 'app-payment', @@ -22,11 +23,12 @@ export class PaymentComponent implements OnInit { ngOnInit() { this.foiRequest = this.dataService.getCurrentState(); - const feeDetails = { + const feeDetails: FeeRequestDetails = { selectedMinistry: this.foiRequest.requestData[this.ministryKey].ministry } + const currentDate = new Date(); - this.dataService.getFeeDetails(this.feeCode, feeDetails).subscribe(result => { + this.dataService.getFeeDetails(this.feeCode, currentDate.toISOString(), feeDetails).subscribe(result => { this.fee = result.fee; this.isBusy = false; }, error => { diff --git a/web/src/app/services/data.service.ts b/web/src/app/services/data.service.ts index 6b323f71..69951c48 100644 --- a/web/src/app/services/data.service.ts +++ b/web/src/app/services/data.service.ts @@ -5,6 +5,7 @@ import { FoiRoute } from '../models/FoiRoute'; import { FoiRequest, BlobFile } from '../models/FoiRequest'; import { TransomApiClientService } from '../transom-api-client.service'; import { FormGroup } from '@angular/forms'; +import { FeeRequestDetails } from '../models/FeeRequestDetails'; @Injectable({ providedIn: 'root' @@ -242,9 +243,38 @@ export class DataService { return this.apiClient.postFoiRequest(foiRequest); } - getFeeDetails(feeCode: String, details?: Object): Observable { + /** + * Fetches the fee details according to the fee code and the quantity of the fee units. + * A selected ministry could be a fee unit and the number of selected ministries could be the quantity. + * + * @param feeCode + * @param date + * @param details - The details that would affect the calculation of the quantity of fee units e.g. ministries selected + */ + getFeeDetails(feeCode: String, date: string, details?: FeeRequestDetails): Observable { + const quantity = details? this.calculateUnitFeeQuantity(details) : 1; + + /* + uncomment to test page + return of({fee: 10}) + */ + + return this.apiClient.getFeeDetails(feeCode, quantity, date); + } + + /** + * Calculates the quantity of fee units. + * e.g. total fee amount could be fee * number of ministries selected (fee units) + * + * @param details - The details that would affect the calculation of the quantity of fee units e.g. ministries selected + */ + private calculateUnitFeeQuantity(details: FeeRequestDetails): Number { + if(!details.selectedMinistry || details.selectedMinistry.length < 2) { + return 1; + } - return this.apiClient.getFeeDetails(feeCode, details); + //current calculation is just the number of selected ministries + return details.selectedMinistry.length; } /** diff --git a/web/src/app/transom-api-client.service.ts b/web/src/app/transom-api-client.service.ts index c3701e19..29e34979 100644 --- a/web/src/app/transom-api-client.service.ts +++ b/web/src/app/transom-api-client.service.ts @@ -29,7 +29,7 @@ export class TransomApiClientService { constructor(public http: HttpClient, private storage: LocalStorageService) { this.baseUrl = "/api/v1"; - this.requestManagementUrl = ""; + this.requestManagementUrl = "/api"; this.headers = {}; } @@ -102,10 +102,10 @@ export class TransomApiClientService { return this.handleResponse(obs); } - getFeeDetails(feeCode: String, details?: Object): Observable { - const url = this.requestManagementUrl + `/payments/${feeCode}` + getFeeDetails(feeCode: String, quantity: Number, date: string): Observable { + const url = this.requestManagementUrl + `/payments/${feeCode}?quantity=${quantity}&date=${date}` - const obs = this.http.post(url, JSON.stringify(details), { + const obs = this.http.get(url, { headers: this.headers }); return this.handleResponse(obs); diff --git a/web/src/proxy.conf.json b/web/src/proxy.conf.json index d0f48793..27535801 100644 --- a/web/src/proxy.conf.json +++ b/web/src/proxy.conf.json @@ -4,9 +4,14 @@ "changeOrigin": true, "secure": false }, - "/api": { + "/api/v1": { "target": "http://localhost:7085", "changeOrigin": true, "secure": false + }, + "/api": { + "target": "http://localhost:15000", + "changeOrigin": true, + "secure": false } } From 2dc5b041ea0671f20f7d1dfaa2987c9d5539d716 Mon Sep 17 00:00:00 2001 From: Jad Date: Fri, 15 Oct 2021 19:28:58 -0700 Subject: [PATCH 140/589] Add collecting payment flow for FOI Web --- web/src/app/models/Transaction.ts | 18 +++++++ .../payment-complete.component.html | 24 +++++++++ .../payment-complete.component.scss | 0 .../payment-complete.component.spec.ts | 25 ++++++++++ .../payment-complete.component.ts | 49 +++++++++++++++++++ .../payment/payment.component.ts | 38 +++++++++++++- .../route-components.module.ts | 2 + web/src/app/services/data.service.ts | 11 +++++ web/src/app/services/window-ref.service.ts | 8 +++ web/src/app/transom-api-client.service.ts | 24 +++++++++ 10 files changed, 197 insertions(+), 2 deletions(-) create mode 100644 web/src/app/models/Transaction.ts create mode 100644 web/src/app/route-components/payment-complete/payment-complete.component.html create mode 100644 web/src/app/route-components/payment-complete/payment-complete.component.scss create mode 100644 web/src/app/route-components/payment-complete/payment-complete.component.spec.ts create mode 100644 web/src/app/route-components/payment-complete/payment-complete.component.ts diff --git a/web/src/app/models/Transaction.ts b/web/src/app/models/Transaction.ts new file mode 100644 index 00000000..7d6fb8b1 --- /dev/null +++ b/web/src/app/models/Transaction.ts @@ -0,0 +1,18 @@ +/** + * Interface definition for the create transaction request. + */ + export interface CreateTransactionRequest { + feeCode: string, + fee: string, + requestId: Number + payReturnUrl: string +} + +/** + * Interface definition for the update of transactions. + */ + export interface UpdateTransactionRequest { + payResponseUrl: string, + transactionId: Number, + requestId: Number +} \ No newline at end of file diff --git a/web/src/app/route-components/payment-complete/payment-complete.component.html b/web/src/app/route-components/payment-complete/payment-complete.component.html new file mode 100644 index 00000000..c968505a --- /dev/null +++ b/web/src/app/route-components/payment-complete/payment-complete.component.html @@ -0,0 +1,24 @@ + +
    +

    Payment

    +

    + We have successfully received your payment. Please proceed. +

    +

    + We had an issue while trying to process your payment. Please retry after a few minutes. +

    + +
    + +
    + +
    + +
    \ No newline at end of file diff --git a/web/src/app/route-components/payment-complete/payment-complete.component.scss b/web/src/app/route-components/payment-complete/payment-complete.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/payment-complete/payment-complete.component.spec.ts b/web/src/app/route-components/payment-complete/payment-complete.component.spec.ts new file mode 100644 index 00000000..fa453794 --- /dev/null +++ b/web/src/app/route-components/payment-complete/payment-complete.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { PaymentCompleteComponent } from './payment-complete.component'; + +describe('PaymentCompleteComponent', () => { + let component: PaymentCompleteComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ PaymentCompleteComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(PaymentCompleteComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/web/src/app/route-components/payment-complete/payment-complete.component.ts b/web/src/app/route-components/payment-complete/payment-complete.component.ts new file mode 100644 index 00000000..23e91e39 --- /dev/null +++ b/web/src/app/route-components/payment-complete/payment-complete.component.ts @@ -0,0 +1,49 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { DataService } from 'src/app/services/data.service'; +import { BaseComponent } from 'src/app/utils-components/base/base.component'; + +@Component({ + selector: 'app-payment-complete', + templateUrl: './payment-complete.component.html', + styleUrls: ['./payment-complete.component.scss'] +}) +export class PaymentCompleteComponent implements OnInit { + @ViewChild(BaseComponent) base: BaseComponent; + busy= true + paymentSuccess= false; + transactionId = null; + requestId= null; + payResponseUrl= null; + + constructor(private dataService: DataService, private route: ActivatedRoute) { } + + ngOnInit() { + this.route.queryParams.subscribe(params => { + this.transactionId = params.transactionId + this.requestId = params.requestId; + this.payResponseUrl = params.payResponseUrl; + this.updateTransaction(); + }); + } + + updateTransaction() { + this.dataService.updateTransaction({ + transactionId: this.transactionId, + requestId: this.requestId, + payResponseUrl: this.payResponseUrl + }).subscribe(result => { + if (result.statusCode === 'COMPLETED') { + this.paymentSuccess = true; + this.busy = false; + } else { + this.paymentSuccess = false; + this.busy = false; + } + }) + } + + doContinue() { + this.base.goFoiForward(); + } +} diff --git a/web/src/app/route-components/payment/payment.component.ts b/web/src/app/route-components/payment/payment.component.ts index b67a6691..e06b2f00 100644 --- a/web/src/app/route-components/payment/payment.component.ts +++ b/web/src/app/route-components/payment/payment.component.ts @@ -3,6 +3,7 @@ import { DataService } from 'src/app/services/data.service'; import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { FeeRequestDetails } from 'src/app/models/FeeRequestDetails'; +import { WindowRefService } from 'src/app/services/window-ref.service'; @Component({ selector: 'app-payment', @@ -15,10 +16,10 @@ export class PaymentComponent implements OnInit { foiRequest: FoiRequest; feeCode = 'FOI010' isBusy = true; - + payBusy = false; ministryKey = "ministry" - constructor(private dataService: DataService) { } + constructor(private dataService: DataService, private windowRefService: WindowRefService ) { } ngOnInit() { this.foiRequest = this.dataService.getCurrentState(); @@ -45,6 +46,39 @@ export class PaymentComponent implements OnInit { } doContinue() { + this.payBusy = true; + this.doCreateTransaction() + .subscribe(transactionDetails => { + if(transactionDetails.paySystemUrl) { + this.windowRefService.goToUrl(transactionDetails.paySystemUr) + } + else { + this.transactionError(); + } + }, error => { + console.log('Submission failed: ', error); + this.transactionError() + }) + } + + private transactionError() { + this.isBusy = false; + alert('Temporary unable to proceed to payment. Please try again in a few minutes.'); + } + + private doCreateTransaction () { + return this.dataService.createTransaction({ + feeCode: this.feeCode, + fee: this.fee, + requestId: this.foiRequest.requestData.requestId, + payReturnUrl: this.getReturnUrl() + }) + } + private getReturnUrl() { + const nextRoute = this.dataService.getRoute(this.base.getCurrentRoute()).forward || + this.base.getCurrentRoute() + "-return"; + const fullUrl = window.location.origin + "/" + nextRoute; + return fullUrl; } } diff --git a/web/src/app/route-components/route-components.module.ts b/web/src/app/route-components/route-components.module.ts index 588ad204..9ea769c6 100644 --- a/web/src/app/route-components/route-components.module.ts +++ b/web/src/app/route-components/route-components.module.ts @@ -29,6 +29,7 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { library } from '@fortawesome/fontawesome-svg-core'; import { faSpinner } from '@fortawesome/free-solid-svg-icons'; import { PaymentComponent } from './payment/payment.component'; +import { PaymentCompleteComponent } from './payment-complete/payment-complete.component'; // Add an icon to the library for convenient access in other components library.add(faSpinner); @@ -58,6 +59,7 @@ library.add(faSpinner); AnotherInformationComponent, AdoptiveParentsComponent, PaymentComponent, + PaymentCompleteComponent, ], imports: [ // Required to use these in children of RouteComponentsModule diff --git a/web/src/app/services/data.service.ts b/web/src/app/services/data.service.ts index 69951c48..85db00f0 100644 --- a/web/src/app/services/data.service.ts +++ b/web/src/app/services/data.service.ts @@ -6,6 +6,7 @@ import { FoiRequest, BlobFile } from '../models/FoiRequest'; import { TransomApiClientService } from '../transom-api-client.service'; import { FormGroup } from '@angular/forms'; import { FeeRequestDetails } from '../models/FeeRequestDetails'; +import { CreateTransactionRequest, UpdateTransactionRequest } from '../models/Transaction'; @Injectable({ providedIn: 'root' @@ -262,6 +263,16 @@ export class DataService { return this.apiClient.getFeeDetails(feeCode, quantity, date); } + createTransaction(transactionRequest: CreateTransactionRequest) { + + return this.apiClient.createTransaction(transactionRequest); + } + + updateTransaction(updateTransactionRequest: UpdateTransactionRequest) { + + return this.apiClient.updateTransaction(updateTransactionRequest); + } + /** * Calculates the quantity of fee units. * e.g. total fee amount could be fee * number of ministries selected (fee units) diff --git a/web/src/app/services/window-ref.service.ts b/web/src/app/services/window-ref.service.ts index 4b96d6b8..2e80a3cd 100644 --- a/web/src/app/services/window-ref.service.ts +++ b/web/src/app/services/window-ref.service.ts @@ -20,4 +20,12 @@ export class WindowRefService { get nativeWindow(): any { return _window(); } + + /** + * Changes location.href in the window object to cause redirect + * + */ + goToUrl (url:string) { + window.location.href = url; + } } diff --git a/web/src/app/transom-api-client.service.ts b/web/src/app/transom-api-client.service.ts index 29e34979..dde0cde7 100644 --- a/web/src/app/transom-api-client.service.ts +++ b/web/src/app/transom-api-client.service.ts @@ -5,6 +5,7 @@ import { HttpClient, HttpErrorResponse } from "@angular/common/http"; import { map, catchError } from "rxjs/operators"; import { LocalStorageService } from "ngx-webstorage"; import { FoiRequest, BlobFile } from "./models/FoiRequest"; +import { CreateTransactionRequest } from "./models/Transaction"; /** * Generic implementation of calls to the API. It supports making @@ -102,6 +103,29 @@ export class TransomApiClientService { return this.handleResponse(obs); } + createTransaction(transactionRequest): Observable { + const url = this.requestManagementUrl + `/payments/createTransaction`; + + const obs = this.http.post(url, JSON.stringify(transactionRequest), { + headers: this.headers + }); + return this.handleResponse(obs); + } + + updateTransaction(updateTransactionRequest): Observable { + const {requestId, payResponseUrl, transactionId} = updateTransactionRequest; + + const url = this.requestManagementUrl + `/payments/${requestId}/transactions/${transactionId}`; + + const obs = this.http.patch(url, JSON.stringify({ + payResponseUrl: payResponseUrl + }), { + headers: this.headers + }); + + return this.handleResponse(obs); + } + getFeeDetails(feeCode: String, quantity: Number, date: string): Observable { const url = this.requestManagementUrl + `/payments/${feeCode}?quantity=${quantity}&date=${date}` From 0dc09121282e62ec439a5e7947914ad0a2ec1493 Mon Sep 17 00:00:00 2001 From: Jad Date: Fri, 15 Oct 2021 20:54:56 -0700 Subject: [PATCH 141/589] Send FOI Request email after payment is complete --- .../payment-complete.component.html | 2 +- .../payment-complete.component.ts | 26 +++++++++++++++++-- .../review-submit/review-submit.component.ts | 2 ++ web/src/app/services/data.service.ts | 18 ++++++++++++- web/src/app/transom-api-client.service.ts | 4 +-- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/web/src/app/route-components/payment-complete/payment-complete.component.html b/web/src/app/route-components/payment-complete/payment-complete.component.html index c968505a..0c959124 100644 --- a/web/src/app/route-components/payment-complete/payment-complete.component.html +++ b/web/src/app/route-components/payment-complete/payment-complete.component.html @@ -2,7 +2,7 @@

    Payment

    - We have successfully received your payment. Please proceed. + We have successfully received your payment. Please proceed to complete your request.

    We had an issue while trying to process your payment. Please retry after a few minutes. diff --git a/web/src/app/route-components/payment-complete/payment-complete.component.ts b/web/src/app/route-components/payment-complete/payment-complete.component.ts index 23e91e39..384dd2b4 100644 --- a/web/src/app/route-components/payment-complete/payment-complete.component.ts +++ b/web/src/app/route-components/payment-complete/payment-complete.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; +import { FoiRequest } from 'src/app/models/FoiRequest'; import { DataService } from 'src/app/services/data.service'; import { BaseComponent } from 'src/app/utils-components/base/base.component'; @@ -10,11 +11,15 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; }) export class PaymentCompleteComponent implements OnInit { @ViewChild(BaseComponent) base: BaseComponent; - busy= true + busy= true; + completeBusy= false; paymentSuccess= false; transactionId = null; requestId= null; payResponseUrl= null; + foiRequest: FoiRequest; + authToken= null; + captchaNonce= null; constructor(private dataService: DataService, private route: ActivatedRoute) { } @@ -25,6 +30,9 @@ export class PaymentCompleteComponent implements OnInit { this.payResponseUrl = params.payResponseUrl; this.updateTransaction(); }); + this.foiRequest = this.dataService.getCurrentState(); + this.authToken = this.dataService.getAuthToken(); + this.captchaNonce = this.dataService.getCaptchaNonce(); } updateTransaction() { @@ -44,6 +52,20 @@ export class PaymentCompleteComponent implements OnInit { } doContinue() { - this.base.goFoiForward(); + this.completeBusy= true; + this.submitEmail(); + } + + submitEmail() { + this.dataService.submitRequest(this.authToken, this.captchaNonce, this.foiRequest, true).subscribe(result => { + if(result.EmailSuccess) { + this.base.goFoiForward(); + } + }, error => { + this.completeBusy = false; + console.log('Email submission failed: ', error); + alert('Temporarily unable to complete your request. Please try again in a few minutes.' + + ' If you\'re still having issues please contact us to complete your request.'); + }) } } diff --git a/web/src/app/route-components/review-submit/review-submit.component.ts b/web/src/app/route-components/review-submit/review-submit.component.ts index 8c565c86..12152daf 100644 --- a/web/src/app/route-components/review-submit/review-submit.component.ts +++ b/web/src/app/route-components/review-submit/review-submit.component.ts @@ -63,6 +63,8 @@ export class ReviewSubmitComponent implements OnInit { this.foiRequest.requestData.requestId = result.id; this.dataService.setCurrentState(this.foiRequest); + this.dataService.saveAuthToken(this.authToken) + this.dataService.saveCaptchaNonce(this.captchaNonce) this.isBusy = false; // If the user is authenticated, logout the user diff --git a/web/src/app/services/data.service.ts b/web/src/app/services/data.service.ts index 85db00f0..7a4362d0 100644 --- a/web/src/app/services/data.service.ts +++ b/web/src/app/services/data.service.ts @@ -112,6 +112,22 @@ export class DataService { }); } + saveAuthToken(value: string): void { + sessionStorage.setItem("authToken", value); + } + + getAuthToken(): string { + return sessionStorage.getItem("authToken"); + } + + saveCaptchaNonce(value: string): void { + sessionStorage.setItem("captchaNonce", value); + } + + getCaptchaNonce(): string { + return sessionStorage.getItem("captchaNonce"); + } + getShowBanner() { return sessionStorage.getItem('showBanner'); } @@ -213,7 +229,7 @@ export class DataService { * @param nonce * @param foiRequest - A structure containing the complete request */ - submitRequest(authToken: string, nonce: string, foiRequest: FoiRequest): Observable { + submitRequest(authToken: string, nonce: string, foiRequest: FoiRequest, sendEmailOnly?: boolean): Observable { this.apiClient.setHeader('Authorization', 'Bearer ' + authToken); this.apiClient.setHeader('captcha-nonce', nonce); foiRequest.attachments = []; diff --git a/web/src/app/transom-api-client.service.ts b/web/src/app/transom-api-client.service.ts index dde0cde7..db102500 100644 --- a/web/src/app/transom-api-client.service.ts +++ b/web/src/app/transom-api-client.service.ts @@ -86,8 +86,8 @@ export class TransomApiClientService { * the functions object of apiDefinition.js (line 122) * @param body The body to post to the request. */ - postFoiRequest(foiRequest: FoiRequest): Observable { - const functionName = "submitFoiRequest"; + postFoiRequest(foiRequest: FoiRequest, sendEmailOnly?: boolean): Observable { + const functionName = sendEmailOnly ? "submitFoiRequestEmail" : "submitFoiRequest"; const url = this.baseUrl + `/fx/${functionName}`; const body: FormData = new FormData(); From 7cece313871735d1c59fb04e104cfdbfb19c2bf0 Mon Sep 17 00:00:00 2001 From: Jad Date: Mon, 18 Oct 2021 14:45:12 -0700 Subject: [PATCH 142/589] Send request to foi inbox after payment is complete --- api/apiCustomFunctions.js | 124 ++++++++++++++---- api/apiDefinition.js | 5 + web/src/app/app-routing.module.ts | 2 + .../payment/payment.component.html | 1 - .../payment/payment.component.ts | 4 +- web/src/app/services/data.service.ts | 2 +- 6 files changed, 109 insertions(+), 29 deletions(-) diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index 1cae420e..83f9bb35 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -32,30 +32,8 @@ const submitFoiRequest = async (server, req, res, next) => { req.log.info(`Sending message to ${foiRequestInbox}`, data); const foiHtml = emailLayout.renderEmail(data.params,req.isAuthorised,req.userDetails); - const foiAttachments = []; - const filesBase64 = []; - if (req.files) { - Object.keys(req.files).map(f => { - const file = req.files[f]; - if (file.size < maxAttachBytes) { - const filedata = fs.readFileSync(file.path, {encoding: 'base64'}); - - filesBase64.push({ - filename:file.name, - base64data:filedata - }); - - foiAttachments.push({ - filename: file.name, - path: file.path - }); - } else { - const tooLarge = new restifyErrors.PayloadTooLargeError(`Attachment is too large! Max file size is ${maxAttachBytes} bytes.`); - console.log('Attachment too large; size:', file.size, 'max:', maxAttachBytes); - return next(tooLarge); - } - }); - } + const foiAttachments = getAttachments(req, maxAttachBytes, next); + const filesBase64 = getFileBase64(req, maxAttachBytes, next); console.log("calling RAW FOI Request"); if (req.files) { @@ -101,6 +79,49 @@ const submitFoiRequest = async (server, req, res, next) => { } } +const submitFoiRequestEmail = async (server, req, res, next) => { + + const emailLayout = new EmailLayout(); + const foiRequestInbox = process.env.FOI_REQUEST_INBOX; + + const MAX_ATTACH_MB = 5; + const maxAttachBytes = MAX_ATTACH_MB * 1024 *1024; + + req.params.requestData = JSON.parse(req.params.requestData); + + const data = { + envMessage: process.env.NODE_ENV, + params: req.params, + files: req.files + }; + req.log.info(`Sending message to ${foiRequestInbox}`, data); + + const foiHtml = emailLayout.renderEmail(data.params,req.isAuthorised,req.userDetails); + const foiAttachments = getAttachments(req, maxAttachBytes, next); + + try { + + const sentResponse = await sendEmail(foiHtml,foiAttachments); + + if(sentResponse.EmailSuccess) { + req.log.info('FOI Request email submission success'); + res.send({EmailSuccess: true, message: 'success'}); + next(); + } + else { + console.log(sentResponse.message); + const unavailable = new restifyErrors.ServiceUnavailableError(sentResponse.message || 'Service is unavailable.'); + return next(unavailable); + } + } + catch(error){ + console.log(`${error}`); + req.log.info('Failed:', error); + const unavailable = new restifyErrors.ServiceUnavailableError('Service is unavailable.'); + return next(unavailable); + } +} + const sendEmail = async (foiHtml, foiAttachments) => { var EmailSuccess = true; var message = ""; @@ -134,4 +155,57 @@ const sendEmail = async (foiHtml, foiAttachments) => { console.log(`Sent Email? : ${EmailSuccess}, Message: ${message}`); return { EmailSuccess, message }; } -module.exports = { submitFoiRequest }; \ No newline at end of file + +const getAttachments = (req, maxAttachBytes, filesBase64, foiAttachments, next) => { + + const attachments = []; + if (req.files) { + Object.keys(req.files).map(f => { + const file = req.files[f]; + if (file.size < maxAttachBytes) { + const filedata = fs.readFileSync(file.path, { encoding: 'base64' }); + + filesBase64.push({ + filename: file.name, + base64data: filedata + }); + + attachments.push({ + filename: file.name, + path: file.path + }); + return attachments; + } else { + const tooLarge = new restifyErrors.PayloadTooLargeError(`Attachment is too large! Max file size is ${maxAttachBytes} bytes.`); + console.log('Attachment too large; size:', file.size, 'max:', maxAttachBytes); + return next(tooLarge); + } + }); + } +} + +const getFileBase64 = (req, maxAttachBytes, next) => { + + const filesBase64 = []; + if (req.files) { + Object.keys(req.files).map(f => { + const file = req.files[f]; + if (file.size < maxAttachBytes) { + const filedata = fs.readFileSync(file.path, { encoding: 'base64' }); + + filesBase64.push({ + filename: file.name, + base64data: filedata + }); + + return filesBase64; + } else { + const tooLarge = new restifyErrors.PayloadTooLargeError(`Attachment is too large! Max file size is ${maxAttachBytes} bytes.`); + console.log('Attachment too large; size:', file.size, 'max:', maxAttachBytes); + return next(tooLarge); + } + }); + } +} + +module.exports = { submitFoiRequest, submitFoiRequestEmail}; \ No newline at end of file diff --git a/api/apiDefinition.js b/api/apiDefinition.js index 53d6747a..44737e93 100644 --- a/api/apiDefinition.js +++ b/api/apiDefinition.js @@ -53,6 +53,11 @@ module.exports = { methods: ['POST'], preMiddleware: [apiAuth.verifyJWTResponseMiddleware, apiCaptcha.verifyJWTResponseMiddleware], function: customFunctions.submitFoiRequest + }, + submitFoiRequestEmail: { + methods: ['POST'], + preMiddleware: [apiAuth.verifyJWTResponseMiddleware, apiCaptcha.verifyJWTResponseMiddleware], + function: customFunctions.submitFoiRequestEmail } } } diff --git a/web/src/app/app-routing.module.ts b/web/src/app/app-routing.module.ts index 0d82e2a0..e3ebfaa6 100644 --- a/web/src/app/app-routing.module.ts +++ b/web/src/app/app-routing.module.ts @@ -21,6 +21,7 @@ import { ReviewSubmitCompleteComponent } from './route-components/review-submit- import { AdoptiveParentsComponent } from './route-components/adoptive-parents/adoptive-parents.component'; import { SigninComponent } from './route-components/signin/signin.component'; import { PaymentComponent } from './route-components/payment/payment.component'; +import { PaymentCompleteComponent } from './route-components/payment-complete/payment-complete.component'; const routes: Routes = [ { path: '', component: LandingComponent }, @@ -39,6 +40,7 @@ const routes: Routes = [ { path: 'general/review-submit', component: ReviewSubmitComponent }, { path: 'general/submit-complete', component: ReviewSubmitCompleteComponent}, { path: 'general/payment', component: PaymentComponent}, + { path: 'general/payment-complete', component: PaymentCompleteComponent}, // Personal { path: 'personal/select-about', component: SelectAboutComponent }, diff --git a/web/src/app/route-components/payment/payment.component.html b/web/src/app/route-components/payment/payment.component.html index 2dc68a83..7c1b3530 100644 --- a/web/src/app/route-components/payment/payment.component.html +++ b/web/src/app/route-components/payment/payment.component.html @@ -9,7 +9,6 @@

    Fee details

    -
    diff --git a/web/src/app/route-components/payment-complete/payment-complete.component.ts b/web/src/app/route-components/payment-complete/payment-complete.component.ts index 828c6aba..12e9e9a6 100644 --- a/web/src/app/route-components/payment-complete/payment-complete.component.ts +++ b/web/src/app/route-components/payment-complete/payment-complete.component.ts @@ -3,6 +3,7 @@ import { ActivatedRoute } from '@angular/router'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { DataService } from 'src/app/services/data.service'; import { BaseComponent } from 'src/app/utils-components/base/base.component'; +import { WindowRefService } from 'src/app/services/window-ref.service'; @Component({ selector: 'app-payment-complete', @@ -12,7 +13,6 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; export class PaymentCompleteComponent implements OnInit { @ViewChild(BaseComponent) base: BaseComponent; busy= true; - completeBusy= false; paymentSuccess= false; paymentId = null; requestId= null; @@ -20,20 +20,34 @@ export class PaymentCompleteComponent implements OnInit { foiRequest: FoiRequest; authToken= null; captchaNonce= null; + paybcUrl= null; + retry = false; - constructor(private dataService: DataService, private route: ActivatedRoute) { } + transactionNumber = null; + amount = null; + paymentStatusMessage = null; + constructor(private dataService: DataService, private route: ActivatedRoute, private windowRefService: WindowRefService) { } + ngOnInit() { + this.route.queryParams.subscribe(queryParams => { + this.transactionNumber = queryParams.pbcTxnNumber; + this.amount = queryParams.trnAmount; + this.paymentStatusMessage = queryParams.messageText; + }) + this.route.params.subscribe(params => { this.paymentId = params.paymentId this.requestId = params.requestId; this.responseUrl = window.location.href.split('?')[1] + + this.foiRequest = this.dataService.getCurrentState(); + this.foiRequest.requestData.requestId = this.paymentId; + this.dataService.setCurrentState(this.foiRequest); + this.updateTransaction(); + }); - this.foiRequest = this.dataService.getCurrentState(); - - this.foiRequest.requestData.requestId = this.paymentId; - this.dataService.setCurrentState(this.foiRequest); this.authToken = this.dataService.getAuthToken(); this.captchaNonce = this.dataService.getCaptchaNonce(); @@ -47,29 +61,38 @@ export class PaymentCompleteComponent implements OnInit { }).subscribe(result => { if (result.status === 'PAID') { this.paymentSuccess = true; - this.busy = false; + this.submitEmail(); } else { this.paymentSuccess = false; - this.busy = false; + + if(result.paybc_url) { + this.retry = true; + this.paybcUrl = result.paybc_url + } else { + alert(`It seems there was an error completing your payment of transaction number: ${this.transactionNumber}.` + + `Please contact us to investigate`) + + } } }) } doContinue() { - this.completeBusy= true; - this.submitEmail(); + this.base.goFoiForward(); + } + + doRetry() { + this.windowRefService.goToUrl(this.paybcUrl) } submitEmail() { this.dataService.submitRequest(this.authToken, this.captchaNonce, this.foiRequest, true).subscribe(result => { - if(result.EmailSuccess) { - this.base.goFoiForward(); + if(!result.EmailSuccess) { + alert('Temporarily unable to complete your request. Please contact us to complete your request.'); } - }, error => { - this.completeBusy = false; + }, error => { console.log('Email submission failed: ', error); - alert('Temporarily unable to complete your request. Please try again in a few minutes.' - + ' If you\'re still having issues please contact us to complete your request.'); + alert('Temporarily unable to complete your request. Please contact us to complete your request.'); }) } } diff --git a/web/src/app/route-components/payment/payment.component.ts b/web/src/app/route-components/payment/payment.component.ts index 5c492825..48e74cab 100644 --- a/web/src/app/route-components/payment/payment.component.ts +++ b/web/src/app/route-components/payment/payment.component.ts @@ -20,7 +20,7 @@ export class PaymentComponent implements OnInit { ministryKey = "ministry" feeDetails: FeeRequestDetails; - constructor(private dataService: DataService, private windowRefService: WindowRefService ) { } + constructor(private dataService: DataService, private windowRefService: WindowRefService) { } ngOnInit() { console.log(this.getReturRoute()) diff --git a/web/src/app/route-components/review-submit-complete/review-submit-complete.component.ts b/web/src/app/route-components/review-submit-complete/review-submit-complete.component.ts index 647ea442..68e7d904 100644 --- a/web/src/app/route-components/review-submit-complete/review-submit-complete.component.ts +++ b/web/src/app/route-components/review-submit-complete/review-submit-complete.component.ts @@ -24,6 +24,8 @@ export class ReviewSubmitCompleteComponent implements OnInit { this.dataService.setCurrentState(blankState); this.dataService.removeChildFileAttachment(); this.dataService.removePersonFileAttachment(); + this.dataService.removeAuthToken(); + this.dataService.removeCaptchaNonce(); } submitAnotherRequest() { diff --git a/web/src/app/services/data.service.ts b/web/src/app/services/data.service.ts index 20a1ee85..c08bed3f 100644 --- a/web/src/app/services/data.service.ts +++ b/web/src/app/services/data.service.ts @@ -125,6 +125,10 @@ export class DataService { return sessionStorage.getItem("authToken"); } + removeAuthToken(): void { + sessionStorage.removeItem("authToken"); + } + saveCaptchaNonce(value: string): void { sessionStorage.setItem("captchaNonce", value); } @@ -133,6 +137,10 @@ export class DataService { return sessionStorage.getItem("captchaNonce"); } + removeCaptchaNonce(): void { + sessionStorage.removeItem("captchaNonce"); + } + getShowBanner() { return sessionStorage.getItem('showBanner'); } From 3f1b7bbddbb23cfb4d539ac36488e421bdc07ee9 Mon Sep 17 00:00:00 2001 From: Jad Date: Mon, 25 Oct 2021 12:12:03 -0700 Subject: [PATCH 157/589] Change fee name to application fee --- web/src/app/route-components/payment/payment.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/src/app/route-components/payment/payment.component.html b/web/src/app/route-components/payment/payment.component.html index 5630d2de..2de07303 100644 --- a/web/src/app/route-components/payment/payment.component.html +++ b/web/src/app/route-components/payment/payment.component.html @@ -2,7 +2,7 @@

    Fee details

    - This basic fee is calculated based on your selections + This application fee is calculated based on your selections

    We have calculated that the basic fee of this application is: ${{fee}} From 6ed52578a7de969709bc51febdcb75873069be0d Mon Sep 17 00:00:00 2001 From: Jad Date: Mon, 25 Oct 2021 15:10:37 -0700 Subject: [PATCH 158/589] Update info displayed in payment page --- .../payment-complete/payment-complete.component.html | 3 ++- .../payment-complete/payment-complete.component.ts | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/web/src/app/route-components/payment-complete/payment-complete.component.html b/web/src/app/route-components/payment-complete/payment-complete.component.html index 9cb0bbd3..c869d603 100644 --- a/web/src/app/route-components/payment-complete/payment-complete.component.html +++ b/web/src/app/route-components/payment-complete/payment-complete.component.html @@ -12,9 +12,10 @@

    Payment

    • Transaction number: {{transactionNumber}}
    • Amount: ${{amount}}
    • -
    • Status: {{paymentStatusMessage}}
    +

    Please write down your transaction number for your reference.

    +
    From ad4f43a00ca209154e53cc7c4326beb1fb7778f9 Mon Sep 17 00:00:00 2001 From: Adam Coard Date: Wed, 8 Jun 2022 10:08:07 -0700 Subject: [PATCH 235/589] Fix API CD script --- .github/workflows/api-cd.test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/api-cd.test.yml b/.github/workflows/api-cd.test.yml index fbf48388..9e485345 100644 --- a/.github/workflows/api-cd.test.yml +++ b/.github/workflows/api-cd.test.yml @@ -48,7 +48,7 @@ jobs: - name: Build from text branch shell: bash run: | - oc patch bc/api-master-build -p '{"spec":{"source":{"git":{"ref":"test"}}}}' + oc patch bc/api-master-build -p '{"spec":{"source":{"git":{"ref":"master"}}}}' - name: Start Build Openshift shell: bash From f2c0c4ccbf13db6247cc4c40b076858288ba9f8b Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Fri, 10 Jun 2022 11:43:21 -0700 Subject: [PATCH 236/589] Enabled CDOGS , tryout on DEV --- api/apiCustomFunctions.js | 35 +++++++++++-------- .../payment-complete.component.html | 4 +-- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index 16e85d48..62c1d6d4 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -90,24 +90,29 @@ const submitFoiRequestEmail = async (server, req, res, next) => { const receipt = []; - // const receiptResponse = await postGenerateReceipt({ - // requestData: req.params.requestData, - // requestId: req.params.requestData.requestId, - // paymentId: req.params.requestData.paymentInfo.paymentId, - // }); - - // if(receiptResponse.status === 200 && receiptResponse.data) { - // var base64String = Buffer.from(receiptResponse.data).toString("base64"); + try{ + const receiptResponse = await postGenerateReceipt({ + requestData: req.params.requestData, + requestId: req.params.requestData.requestId, + paymentId: req.params.requestData.paymentInfo.paymentId, + }); + + if(receiptResponse.status === 200 && receiptResponse.data) { + var base64String = Buffer.from(receiptResponse.data).toString("base64"); - // const receiptAttachement = { - // content: base64String, - // filename: "Receipt.pdf", - // encoding: "base64" - // }; + const receiptAttachement = { + content: base64String, + filename: "Receipt.pdf", + encoding: "base64" + }; - // receipt.push(receiptAttachement) + receipt.push(receiptAttachement) - // } + } + } + catch(genreceipterror){ + console.log(`${genreceipterror}`); + } req.log.info(`Sending message to ${foiRequestInbox}`, req.params); await sendSubmissionEmail(req, next, server, receipt); diff --git a/web/src/app/route-components/payment-complete/payment-complete.component.html b/web/src/app/route-components/payment-complete/payment-complete.component.html index aaabd4c7..3756eae5 100644 --- a/web/src/app/route-components/payment-complete/payment-complete.component.html +++ b/web/src/app/route-components/payment-complete/payment-complete.component.html @@ -28,7 +28,7 @@

    Payment

    > {{ retry ? "Retry payment" : "Continue"}} - +
    From 6baf2fcc1ed11013e88dc9f1b1039e1f78a5afbb Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Fri, 10 Jun 2022 11:48:05 -0700 Subject: [PATCH 237/589] catch block update - DEV try out --- api/apiCustomFunctions.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index 62c1d6d4..cde25dbf 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -111,7 +111,9 @@ const submitFoiRequestEmail = async (server, req, res, next) => { } } catch(genreceipterror){ - console.log(`${genreceipterror}`); + console.log("---submitFoiRequestEmail Generate Receipt Error starts--"); + console.log(genreceipterror); + console.log("---submitFoiRequestEmail Generate Receipt Error ends--"); } req.log.info(`Sending message to ${foiRequestInbox}`, req.params); From e3a830d94c12889d8ea9b41507a4100485710261 Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Mon, 13 Jun 2022 11:59:39 -0700 Subject: [PATCH 238/589] #2305 Reverting temp wording while CDOGS issue. --- api/apiCustomFunctions.js | 1 + .../payment-complete/payment-complete.component.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/api/apiCustomFunctions.js b/api/apiCustomFunctions.js index cde25dbf..56186e57 100644 --- a/api/apiCustomFunctions.js +++ b/api/apiCustomFunctions.js @@ -113,6 +113,7 @@ const submitFoiRequestEmail = async (server, req, res, next) => { catch(genreceipterror){ console.log("---submitFoiRequestEmail Generate Receipt Error starts--"); console.log(genreceipterror); + req.log.info('Generate receipt Error:', genreceipterror); console.log("---submitFoiRequestEmail Generate Receipt Error ends--"); } diff --git a/web/src/app/route-components/payment-complete/payment-complete.component.html b/web/src/app/route-components/payment-complete/payment-complete.component.html index 3756eae5..053a8dbb 100644 --- a/web/src/app/route-components/payment-complete/payment-complete.component.html +++ b/web/src/app/route-components/payment-complete/payment-complete.component.html @@ -16,7 +16,7 @@

    Payment

  • Order id: {{transactionOrderId}}
  • Amount: ${{amount}}
  • -

    Please write down your transaction number for your reference. Receipts are currently unavailable. You will receive confirmation of payment by email.

    +

    Please write down your transaction number for your reference.

    From a1f407b377935ef7431f4a8756cf3e92049586e0 Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Wed, 28 Sep 2022 16:03:59 -0700 Subject: [PATCH 239/589] #2861 request topic options on the list --- web/src/app/services/data.json | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/web/src/app/services/data.json b/web/src/app/services/data.json index 86693d8e..8b8fc1f0 100644 --- a/web/src/app/services/data.json +++ b/web/src/app/services/data.json @@ -30,6 +30,12 @@ { "code": "TRAN", "name": "Transportation and Infrastructure", "publicBody": "Transportation and Infrastructure" } ], "topicYourself": [ + { "value": "childprotectionparent", "text": "Child protection – Parent Submitting Request", "ministryCode": "MCF" }, + { "value": "childprotectionchild", "text": "Child protection – Child Submitting Request", "ministryCode": "MCF" }, + { "value": "youthincareparent", "text": "Youth in care - Parent Submitting Request", "ministryCode": "MCF" }, + { "value": "youthincarechild", "text": "Youth in care - Child Submitting Request", "ministryCode": "MCF" }, + { "value": "fosterparent", "text": "Foster Parent", "ministryCode": "MCF" }, + { "value": "publicServiceEmployment", "text": "Your employment with the public service", @@ -54,6 +60,11 @@ { "value": "anotherTopic", "text": "Other", "ministryCode": null } ], "topicAnother": [ + { "value": "childprotectionparent", "text": "Child protection – Parent Submitting Request", "ministryCode": "MCF" }, + { "value": "childprotectionchild", "text": "Child protection – Child Submitting Request", "ministryCode": "MCF" }, + { "value": "youthincareparent", "text": "Youth in care - Parent Submitting Request", "ministryCode": "MCF" }, + { "value": "youthincarechild", "text": "Youth in care - Child Submitting Request", "ministryCode": "MCF" }, + { "value": "fosterparent", "text": "Foster Parent", "ministryCode": "MCF" }, { "value": "publicServiceEmployment", "text": "The person's employment with the public service", @@ -78,6 +89,11 @@ { "value": "anotherTopic", "text": "Other", "ministryCode": null } ], "topicYourselfAnother": [ + { "value": "childprotectionparent", "text": "Child protection – Parent Submitting Request", "ministryCode": "MCF" }, + { "value": "childprotectionchild", "text": "Child protection – Child Submitting Request", "ministryCode": "MCF" }, + { "value": "youthincareparent", "text": "Youth in care - Parent Submitting Request", "ministryCode": "MCF" }, + { "value": "youthincarechild", "text": "Youth in care - Child Submitting Request", "ministryCode": "MCF" }, + { "value": "fosterparent", "text": "Foster Parent", "ministryCode": "MCF" }, { "value": "publicServiceEmployment", "text": "Employment with the public service", From 261d776d09a33d6f4616727678cee3a40e9709b5 Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Tue, 4 Oct 2022 12:03:59 -0700 Subject: [PATCH 240/589] WIP #2861 --- web/src/app/app-routing.module.ts | 5 +- .../childprotection-parent.component.html | 29 +++++ .../childprotection-parent.component.scss | 0 .../childprotection-parent.component.spec.ts | 0 .../childprotection-parent.component.ts | 48 ++++++++ .../route-components.module.ts | 2 + web/src/app/services/data.json | 110 +++++++++++++++--- 7 files changed, 175 insertions(+), 19 deletions(-) create mode 100644 web/src/app/route-components/childprotection-parent/childprotection-parent.component.html create mode 100644 web/src/app/route-components/childprotection-parent/childprotection-parent.component.scss create mode 100644 web/src/app/route-components/childprotection-parent/childprotection-parent.component.spec.ts create mode 100644 web/src/app/route-components/childprotection-parent/childprotection-parent.component.ts diff --git a/web/src/app/app-routing.module.ts b/web/src/app/app-routing.module.ts index e658f52b..f1171c2b 100644 --- a/web/src/app/app-routing.module.ts +++ b/web/src/app/app-routing.module.ts @@ -22,6 +22,7 @@ import { AdoptiveParentsComponent } from './route-components/adoptive-parents/ad import { SigninComponent } from './route-components/signin/signin.component'; import { PaymentComponent } from './route-components/payment/payment.component'; import { PaymentCompleteComponent } from './route-components/payment-complete/payment-complete.component'; +import { ChildProtectionParent } from './route-components/childprotection-parent/childprotection-parent.component'; const routes: Routes = [ { path: '', component: LandingComponent }, @@ -54,8 +55,10 @@ const routes: Routes = [ // Personal / Yourself { path: 'personal/verify-your-identity', component: VerifyYourIdentityComponent }, { path: 'personal/request-topic', component: RequestTopicComponent }, + { path: 'personal/childprotectionparent', component: ChildProtectionParent }, + { path: 'personal/ministry-confirmation', component: MinistryConfirmationComponent }, - { path: 'personal/description-timeframe', component: DescriptionTimeframeComponent }, + { path: 'personal/description-timeframe', component: DescriptionTimeframeComponent }, { path: 'personal/adoptive-parents', component: AdoptiveParentsComponent }, { path: 'personal/contact-info-options', component: ContactInfoOptionsComponent }, { path: 'personal/review-submit', component: ReviewSubmitComponent }, diff --git a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html new file mode 100644 index 00000000..c206f10f --- /dev/null +++ b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html @@ -0,0 +1,29 @@ + + +
    + + + +
    + + +
    +
    + +
    + +
    + + + + +
    \ No newline at end of file diff --git a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.scss b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.spec.ts b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.ts b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.ts new file mode 100644 index 00000000..a414b582 --- /dev/null +++ b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { BaseComponent } from 'src/app/utils-components/base/base.component'; +import { Validators, FormBuilder, FormGroup } from '@angular/forms'; +import { FoiRequest } from 'src/app/models/FoiRequest'; +import { DataService } from 'src/app/services/data.service'; + + +@Component({ + templateUrl: './childprotection-parent.component.html', + styleUrls: ['./childprotection-parent.component.scss'] +}) +export class ChildProtectionParent implements OnInit { + + @ViewChild(BaseComponent) base: BaseComponent; + + foiForm = this.fb.group({ + childprotectionparentselection: [null, [Validators.required]] + }); + + foiRequest: FoiRequest; + targetKey: string = "childprotectionparent"; + + constructor(private fb: FormBuilder, private dataService: DataService) {} + + ngOnInit() { + + + // Load the current values & populate the FormGroup. + this.foiRequest = this.dataService.getCurrentState(this.targetKey); + this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + } + + doContinue() { + + const formData = this.foiForm.value; + + + // Update save data & proceed. + this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); + this.base.goFoiForward(); + } + + doGoBack() { + this.base.goFoiBack(); + } + + +} diff --git a/web/src/app/route-components/route-components.module.ts b/web/src/app/route-components/route-components.module.ts index 9ea769c6..34bd6918 100644 --- a/web/src/app/route-components/route-components.module.ts +++ b/web/src/app/route-components/route-components.module.ts @@ -16,6 +16,7 @@ import { ContactInfoComponent } from './contact-info/contact-info.component'; import { ReviewSubmitComponent } from './review-submit/review-submit.component'; import { SelectAboutComponent } from './select-about/select-about.component'; import { RequestTopicComponent } from './request-topic/request-topic.component'; +import { ChildProtectionParent } from './childprotection-parent/childprotection-parent.component'; import { ContactInfoOptionsComponent } from './contact-info-options/contact-info-options.component'; import { ProofOfGuardianshipComponent } from './proof-of-guardianship/proof-of-guardianship.component'; import { ChildInformationComponent } from './child-information/child-information.component'; @@ -52,6 +53,7 @@ library.add(faSpinner); ReviewSubmitComponent, SelectAboutComponent, RequestTopicComponent, + ChildProtectionParent, ContactInfoOptionsComponent, ProofOfGuardianshipComponent, ChildInformationComponent, diff --git a/web/src/app/services/data.json b/web/src/app/services/data.json index 8b8fc1f0..922ef5d7 100644 --- a/web/src/app/services/data.json +++ b/web/src/app/services/data.json @@ -172,25 +172,99 @@ "yourself": { "routes": [ { "route": "personal/verify-your-identity", "progress": 2, "data": { "includeBirthDate": true } }, - { - "route": "personal/request-topic", - "data": { - "topics": "topicYourself" + { "route": "personal/request-topic","data": {"topics": "topicYourself" } , + "choices":{ + + + "childprotectionparent":{ + + "routes":[ + { "route": "personal/childprotectionparent","progress": 2}, + { "route": "personal/ministry-confirmation","progress": 2}, + {"route": "personal/description-timeframe","progress": 2}, + { "route": "personal/adoptive-parents","progress": 3}, + {"route": "personal/contact-info-options","progress": 3}, + { "route": "personal/review-submit", "progress": 4 }, + { "route": "personal/submit-complete", "progress": 6 } + ] + }, - "progress": 2 - }, - { - "route": "personal/ministry-confirmation", - "progress": 2 - }, - { - "route": "personal/description-timeframe", - "progress": 2 - }, - { - "route": "personal/adoptive-parents", - "progress": 3 - }, + "childprotectionchild":{ + "routes":[ + { "route": "personal/childprotectionchild","progress": 2}, + { "route": "personal/ministry-confirmation","progress": 2}, + {"route": "personal/description-timeframe","progress": 2}, + { "route": "personal/adoptive-parents","progress": 3}, + {"route": "personal/contact-info-options","progress": 3}, + { "route": "personal/review-submit", "progress": 4 }, + { "route": "personal/submit-complete", "progress": 6 } + ] + + }, + "youthincareparent":{ "routes":[ + { "route": "personal/youthincareparent","progress": 2}, + { "route": "personal/ministry-confirmation","progress": 2}, + {"route": "personal/description-timeframe","progress": 2}, + { "route": "personal/adoptive-parents","progress": 3}, + {"route": "personal/contact-info-options","progress": 3}, + { "route": "personal/review-submit", "progress": 4 }, + { "route": "personal/submit-complete", "progress": 6 } + + ]}, + "youthincarechild":{ "routes":[ + + { "route": "personal/youthincarechild","progress": 2}, + { "route": "personal/ministry-confirmation","progress": 2}, + {"route": "personal/description-timeframe","progress": 2}, + { "route": "personal/adoptive-parents","progress": 3}, + {"route": "personal/contact-info-options","progress": 3}, + { "route": "personal/review-submit", "progress": 4 }, + { "route": "personal/submit-complete", "progress": 6 } + + + ]}, + "fosterparent":{ "routes":[ + + { "route": "personal/fosterparent","progress": 2}, + { "route": "personal/ministry-confirmation","progress": 2}, + {"route": "personal/description-timeframe","progress": 2}, + { "route": "personal/adoptive-parents","progress": 3}, + {"route": "personal/contact-info-options","progress": 3}, + { "route": "personal/review-submit", "progress": 4 }, + { "route": "personal/submit-complete", "progress": 6 } + + ]}, + "adoption":{ "routes":[ + { "route": "personal/adoption","progress": 2}, + { "route": "personal/ministry-confirmation","progress": 2}, + {"route": "personal/description-timeframe","progress": 2}, + { "route": "personal/adoptive-parents","progress": 3}, + {"route": "personal/contact-info-options","progress": 3}, + { "route": "personal/review-submit", "progress": 4 }, + { "route": "personal/submit-complete", "progress": 6 } + + + ]}, + "others":{ + "routes":[ + { "route": "personal/ministry-confirmation","progress": 2}, + {"route": "personal/description-timeframe","progress": 2}, + { "route": "personal/adoptive-parents","progress": 3}, + {"route": "personal/contact-info-options","progress": 3}, + { "route": "personal/review-submit", "progress": 4 }, + { "route": "personal/submit-complete", "progress": 6 } + ] + } + + + + } + }, + + { "route": "personal/ministry-confirmation","progress": 2}, + {"route": "personal/description-timeframe","progress": 2}, + + { "route": "personal/adoptive-parents","progress": 3}, { "route": "personal/contact-info-options", "progress": 3 From c7dd0bba57df0ed534a94e0b928699d4ad8e9fc4 Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Tue, 4 Oct 2022 13:26:59 -0700 Subject: [PATCH 241/589] WIP #2861 Childincatre Child UX Routes --- web/src/app/app-routing.module.ts | 3 +- .../childprotection-child.component.html | 29 +++++++++++ .../childprotection-child.component.scss | 0 .../childprotection-child.component.spec.ts | 0 .../childprotection-child.component.ts | 48 +++++++++++++++++++ .../route-components.module.ts | 2 + 6 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 web/src/app/route-components/childprotection-child/childprotection-child.component.html create mode 100644 web/src/app/route-components/childprotection-child/childprotection-child.component.scss create mode 100644 web/src/app/route-components/childprotection-child/childprotection-child.component.spec.ts create mode 100644 web/src/app/route-components/childprotection-child/childprotection-child.component.ts diff --git a/web/src/app/app-routing.module.ts b/web/src/app/app-routing.module.ts index f1171c2b..561eed23 100644 --- a/web/src/app/app-routing.module.ts +++ b/web/src/app/app-routing.module.ts @@ -23,6 +23,7 @@ import { SigninComponent } from './route-components/signin/signin.component'; import { PaymentComponent } from './route-components/payment/payment.component'; import { PaymentCompleteComponent } from './route-components/payment-complete/payment-complete.component'; import { ChildProtectionParent } from './route-components/childprotection-parent/childprotection-parent.component'; +import { ChildProtectionChild } from './route-components/childprotection-child/childprotection-child.component'; const routes: Routes = [ { path: '', component: LandingComponent }, @@ -56,7 +57,7 @@ const routes: Routes = [ { path: 'personal/verify-your-identity', component: VerifyYourIdentityComponent }, { path: 'personal/request-topic', component: RequestTopicComponent }, { path: 'personal/childprotectionparent', component: ChildProtectionParent }, - + { path: 'personal/childprotectionchild', component: ChildProtectionChild }, { path: 'personal/ministry-confirmation', component: MinistryConfirmationComponent }, { path: 'personal/description-timeframe', component: DescriptionTimeframeComponent }, { path: 'personal/adoptive-parents', component: AdoptiveParentsComponent }, diff --git a/web/src/app/route-components/childprotection-child/childprotection-child.component.html b/web/src/app/route-components/childprotection-child/childprotection-child.component.html new file mode 100644 index 00000000..5997cd4a --- /dev/null +++ b/web/src/app/route-components/childprotection-child/childprotection-child.component.html @@ -0,0 +1,29 @@ + + +
    + + +
    +
    + + +
    +
    + +
    +
    +
    + + + + +
    \ No newline at end of file diff --git a/web/src/app/route-components/childprotection-child/childprotection-child.component.scss b/web/src/app/route-components/childprotection-child/childprotection-child.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/childprotection-child/childprotection-child.component.spec.ts b/web/src/app/route-components/childprotection-child/childprotection-child.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/childprotection-child/childprotection-child.component.ts b/web/src/app/route-components/childprotection-child/childprotection-child.component.ts new file mode 100644 index 00000000..b20574d1 --- /dev/null +++ b/web/src/app/route-components/childprotection-child/childprotection-child.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { BaseComponent } from 'src/app/utils-components/base/base.component'; +import { Validators, FormBuilder, FormGroup } from '@angular/forms'; +import { FoiRequest } from 'src/app/models/FoiRequest'; +import { DataService } from 'src/app/services/data.service'; + + +@Component({ + templateUrl: './childprotection-child.component.html', + styleUrls: ['./childprotection-child.component.scss'] +}) +export class ChildProtectionChild implements OnInit { + + @ViewChild(BaseComponent) base: BaseComponent; + + foiForm = this.fb.group({ + childprotectionchildselection: [null, [Validators.required]] + }); + + foiRequest: FoiRequest; + targetKey: string = "childprotectionchild"; + + constructor(private fb: FormBuilder, private dataService: DataService) {} + + ngOnInit() { + + + // Load the current values & populate the FormGroup. + this.foiRequest = this.dataService.getCurrentState(this.targetKey); + this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + } + + doContinue() { + + const formData = this.foiForm.value; + + + // Update save data & proceed. + this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); + this.base.goFoiForward(); + } + + doGoBack() { + this.base.goFoiBack(); + } + + +} diff --git a/web/src/app/route-components/route-components.module.ts b/web/src/app/route-components/route-components.module.ts index 34bd6918..644f9cc9 100644 --- a/web/src/app/route-components/route-components.module.ts +++ b/web/src/app/route-components/route-components.module.ts @@ -17,6 +17,7 @@ import { ReviewSubmitComponent } from './review-submit/review-submit.component'; import { SelectAboutComponent } from './select-about/select-about.component'; import { RequestTopicComponent } from './request-topic/request-topic.component'; import { ChildProtectionParent } from './childprotection-parent/childprotection-parent.component'; +import { ChildProtectionChild } from './childprotection-child/childprotection-child.component'; import { ContactInfoOptionsComponent } from './contact-info-options/contact-info-options.component'; import { ProofOfGuardianshipComponent } from './proof-of-guardianship/proof-of-guardianship.component'; import { ChildInformationComponent } from './child-information/child-information.component'; @@ -54,6 +55,7 @@ library.add(faSpinner); SelectAboutComponent, RequestTopicComponent, ChildProtectionParent, + ChildProtectionChild, ContactInfoOptionsComponent, ProofOfGuardianshipComponent, ChildInformationComponent, From a50219902531f1021ebfa43a1f5c4783e345ece2 Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Tue, 4 Oct 2022 14:04:30 -0700 Subject: [PATCH 242/589] WIP Components Fosterparent, Youth in care #2861 --- web/src/app/app-routing.module.ts | 7 ++- .../foster-parent.component.html | 36 ++++++++++++ .../foster-parent.component.scss | 0 .../foster-parent.component.spec.ts | 0 .../foster-parent/foster-parent.component.ts | 48 ++++++++++++++++ .../route-components.module.ts | 6 ++ .../youthincare-child.component.html | 57 +++++++++++++++++++ .../youthincare-child.component.scss | 0 .../youthincare-child.component.spec.ts | 0 .../youthincare-child.component.ts | 48 ++++++++++++++++ .../youthincare-parent.component.html | 29 ++++++++++ .../youthincare-parent.component.scss | 0 .../youthincare-parent.component.spec.ts | 0 .../youthincare-parent.component.ts | 48 ++++++++++++++++ 14 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 web/src/app/route-components/foster-parent/foster-parent.component.html create mode 100644 web/src/app/route-components/foster-parent/foster-parent.component.scss create mode 100644 web/src/app/route-components/foster-parent/foster-parent.component.spec.ts create mode 100644 web/src/app/route-components/foster-parent/foster-parent.component.ts create mode 100644 web/src/app/route-components/youthincare-child/youthincare-child.component.html create mode 100644 web/src/app/route-components/youthincare-child/youthincare-child.component.scss create mode 100644 web/src/app/route-components/youthincare-child/youthincare-child.component.spec.ts create mode 100644 web/src/app/route-components/youthincare-child/youthincare-child.component.ts create mode 100644 web/src/app/route-components/youthincare-parent/youthincare-parent.component.html create mode 100644 web/src/app/route-components/youthincare-parent/youthincare-parent.component.scss create mode 100644 web/src/app/route-components/youthincare-parent/youthincare-parent.component.spec.ts create mode 100644 web/src/app/route-components/youthincare-parent/youthincare-parent.component.ts diff --git a/web/src/app/app-routing.module.ts b/web/src/app/app-routing.module.ts index 561eed23..3784a3f2 100644 --- a/web/src/app/app-routing.module.ts +++ b/web/src/app/app-routing.module.ts @@ -24,7 +24,9 @@ import { PaymentComponent } from './route-components/payment/payment.component'; import { PaymentCompleteComponent } from './route-components/payment-complete/payment-complete.component'; import { ChildProtectionParent } from './route-components/childprotection-parent/childprotection-parent.component'; import { ChildProtectionChild } from './route-components/childprotection-child/childprotection-child.component'; - +import { YouthInCareParent } from './route-components/youthincare-parent/youthincare-parent.component'; +import { YouthInCareChild } from './route-components/youthincare-child/youthincare-child.component'; +import { FosterParent } from './route-components/foster-parent/foster-parent.component'; const routes: Routes = [ { path: '', component: LandingComponent }, { path: 'getting-started1', component: GettingStarted1Component }, @@ -58,6 +60,9 @@ const routes: Routes = [ { path: 'personal/request-topic', component: RequestTopicComponent }, { path: 'personal/childprotectionparent', component: ChildProtectionParent }, { path: 'personal/childprotectionchild', component: ChildProtectionChild }, + { path: 'personal/youthincareparent', component: YouthInCareParent }, + { path: 'personal/youthincarechild', component: YouthInCareChild }, + { path: 'personal/fosterparent', component: FosterParent }, { path: 'personal/ministry-confirmation', component: MinistryConfirmationComponent }, { path: 'personal/description-timeframe', component: DescriptionTimeframeComponent }, { path: 'personal/adoptive-parents', component: AdoptiveParentsComponent }, diff --git a/web/src/app/route-components/foster-parent/foster-parent.component.html b/web/src/app/route-components/foster-parent/foster-parent.component.html new file mode 100644 index 00000000..1dea0efd --- /dev/null +++ b/web/src/app/route-components/foster-parent/foster-parent.component.html @@ -0,0 +1,36 @@ + + +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    + + + + +
    \ No newline at end of file diff --git a/web/src/app/route-components/foster-parent/foster-parent.component.scss b/web/src/app/route-components/foster-parent/foster-parent.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/foster-parent/foster-parent.component.spec.ts b/web/src/app/route-components/foster-parent/foster-parent.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/foster-parent/foster-parent.component.ts b/web/src/app/route-components/foster-parent/foster-parent.component.ts new file mode 100644 index 00000000..f90fafb0 --- /dev/null +++ b/web/src/app/route-components/foster-parent/foster-parent.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { BaseComponent } from 'src/app/utils-components/base/base.component'; +import { Validators, FormBuilder, FormGroup } from '@angular/forms'; +import { FoiRequest } from 'src/app/models/FoiRequest'; +import { DataService } from 'src/app/services/data.service'; + + +@Component({ + templateUrl: './foster-parent.component.html', + styleUrls: ['./foster-parent.component.scss'] +}) +export class FosterParent implements OnInit { + + @ViewChild(BaseComponent) base: BaseComponent; + + foiForm = this.fb.group({ + fosterparentselection: [null, [Validators.required]] + }); + + foiRequest: FoiRequest; + targetKey: string = "fosterparent"; + + constructor(private fb: FormBuilder, private dataService: DataService) {} + + ngOnInit() { + + + // Load the current values & populate the FormGroup. + this.foiRequest = this.dataService.getCurrentState(this.targetKey); + this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + } + + doContinue() { + + const formData = this.foiForm.value; + + + // Update save data & proceed. + this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); + this.base.goFoiForward(); + } + + doGoBack() { + this.base.goFoiBack(); + } + + +} diff --git a/web/src/app/route-components/route-components.module.ts b/web/src/app/route-components/route-components.module.ts index 644f9cc9..16b45a90 100644 --- a/web/src/app/route-components/route-components.module.ts +++ b/web/src/app/route-components/route-components.module.ts @@ -18,6 +18,9 @@ import { SelectAboutComponent } from './select-about/select-about.component'; import { RequestTopicComponent } from './request-topic/request-topic.component'; import { ChildProtectionParent } from './childprotection-parent/childprotection-parent.component'; import { ChildProtectionChild } from './childprotection-child/childprotection-child.component'; +import { YouthInCareParent } from './youthincare-parent/youthincare-parent.component'; +import { YouthInCareChild } from './youthincare-child/youthincare-child.component'; +import { FosterParent } from './foster-parent/foster-parent.component'; import { ContactInfoOptionsComponent } from './contact-info-options/contact-info-options.component'; import { ProofOfGuardianshipComponent } from './proof-of-guardianship/proof-of-guardianship.component'; import { ChildInformationComponent } from './child-information/child-information.component'; @@ -56,6 +59,9 @@ library.add(faSpinner); RequestTopicComponent, ChildProtectionParent, ChildProtectionChild, + YouthInCareParent, + YouthInCareChild, + FosterParent, ContactInfoOptionsComponent, ProofOfGuardianshipComponent, ChildInformationComponent, diff --git a/web/src/app/route-components/youthincare-child/youthincare-child.component.html b/web/src/app/route-components/youthincare-child/youthincare-child.component.html new file mode 100644 index 00000000..0264cd85 --- /dev/null +++ b/web/src/app/route-components/youthincare-child/youthincare-child.component.html @@ -0,0 +1,57 @@ + + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    + + + + +
    \ No newline at end of file diff --git a/web/src/app/route-components/youthincare-child/youthincare-child.component.scss b/web/src/app/route-components/youthincare-child/youthincare-child.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/youthincare-child/youthincare-child.component.spec.ts b/web/src/app/route-components/youthincare-child/youthincare-child.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/youthincare-child/youthincare-child.component.ts b/web/src/app/route-components/youthincare-child/youthincare-child.component.ts new file mode 100644 index 00000000..9f7e2e15 --- /dev/null +++ b/web/src/app/route-components/youthincare-child/youthincare-child.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { BaseComponent } from 'src/app/utils-components/base/base.component'; +import { Validators, FormBuilder, FormGroup } from '@angular/forms'; +import { FoiRequest } from 'src/app/models/FoiRequest'; +import { DataService } from 'src/app/services/data.service'; + + +@Component({ + templateUrl: './youthincare-child.component.html', + styleUrls: ['./youthincare-child.component.scss'] +}) +export class YouthInCareChild implements OnInit { + + @ViewChild(BaseComponent) base: BaseComponent; + + foiForm = this.fb.group({ + youthincarechildselection: [null, [Validators.required]] + }); + + foiRequest: FoiRequest; + targetKey: string = "youthincarechild"; + + constructor(private fb: FormBuilder, private dataService: DataService) {} + + ngOnInit() { + + + // Load the current values & populate the FormGroup. + this.foiRequest = this.dataService.getCurrentState(this.targetKey); + this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + } + + doContinue() { + + const formData = this.foiForm.value; + + + // Update save data & proceed. + this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); + this.base.goFoiForward(); + } + + doGoBack() { + this.base.goFoiBack(); + } + + +} diff --git a/web/src/app/route-components/youthincare-parent/youthincare-parent.component.html b/web/src/app/route-components/youthincare-parent/youthincare-parent.component.html new file mode 100644 index 00000000..57884311 --- /dev/null +++ b/web/src/app/route-components/youthincare-parent/youthincare-parent.component.html @@ -0,0 +1,29 @@ + + +
    + + +
    +
    + + +
    +
    + +
    +
    +
    + + + + +
    \ No newline at end of file diff --git a/web/src/app/route-components/youthincare-parent/youthincare-parent.component.scss b/web/src/app/route-components/youthincare-parent/youthincare-parent.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/youthincare-parent/youthincare-parent.component.spec.ts b/web/src/app/route-components/youthincare-parent/youthincare-parent.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/youthincare-parent/youthincare-parent.component.ts b/web/src/app/route-components/youthincare-parent/youthincare-parent.component.ts new file mode 100644 index 00000000..60328463 --- /dev/null +++ b/web/src/app/route-components/youthincare-parent/youthincare-parent.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { BaseComponent } from 'src/app/utils-components/base/base.component'; +import { Validators, FormBuilder, FormGroup } from '@angular/forms'; +import { FoiRequest } from 'src/app/models/FoiRequest'; +import { DataService } from 'src/app/services/data.service'; + + +@Component({ + templateUrl: './youthincare-parent.component.html', + styleUrls: ['./youthincare-parent.component.scss'] +}) +export class YouthInCareParent implements OnInit { + + @ViewChild(BaseComponent) base: BaseComponent; + + foiForm = this.fb.group({ + youthincareparentselection: [null, [Validators.required]] + }); + + foiRequest: FoiRequest; + targetKey: string = "youthincareparent"; + + constructor(private fb: FormBuilder, private dataService: DataService) {} + + ngOnInit() { + + + // Load the current values & populate the FormGroup. + this.foiRequest = this.dataService.getCurrentState(this.targetKey); + this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + } + + doContinue() { + + const formData = this.foiForm.value; + + + // Update save data & proceed. + this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); + this.base.goFoiForward(); + } + + doGoBack() { + this.base.goFoiBack(); + } + + +} From 1460e5a18c871847a2b32509b55f794694ced4f7 Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Tue, 4 Oct 2022 14:17:37 -0700 Subject: [PATCH 243/589] WIP Adoption Component #2861 --- web/src/app/app-routing.module.ts | 2 + .../adoption/adoption.component.html | 43 +++++++++++++++++ .../adoption/adoption.component.scss | 0 .../adoption/adoption.component.spec.ts | 0 .../adoption/adoption.component.ts | 48 +++++++++++++++++++ .../route-components.module.ts | 2 + 6 files changed, 95 insertions(+) create mode 100644 web/src/app/route-components/adoption/adoption.component.html create mode 100644 web/src/app/route-components/adoption/adoption.component.scss create mode 100644 web/src/app/route-components/adoption/adoption.component.spec.ts create mode 100644 web/src/app/route-components/adoption/adoption.component.ts diff --git a/web/src/app/app-routing.module.ts b/web/src/app/app-routing.module.ts index 3784a3f2..e9ed8ba8 100644 --- a/web/src/app/app-routing.module.ts +++ b/web/src/app/app-routing.module.ts @@ -27,6 +27,7 @@ import { ChildProtectionChild } from './route-components/childprotection-child/c import { YouthInCareParent } from './route-components/youthincare-parent/youthincare-parent.component'; import { YouthInCareChild } from './route-components/youthincare-child/youthincare-child.component'; import { FosterParent } from './route-components/foster-parent/foster-parent.component'; +import { Adoption } from './route-components/adoption/adoption.component'; const routes: Routes = [ { path: '', component: LandingComponent }, { path: 'getting-started1', component: GettingStarted1Component }, @@ -63,6 +64,7 @@ const routes: Routes = [ { path: 'personal/youthincareparent', component: YouthInCareParent }, { path: 'personal/youthincarechild', component: YouthInCareChild }, { path: 'personal/fosterparent', component: FosterParent }, + { path: 'personal/adoption', component: Adoption }, { path: 'personal/ministry-confirmation', component: MinistryConfirmationComponent }, { path: 'personal/description-timeframe', component: DescriptionTimeframeComponent }, { path: 'personal/adoptive-parents', component: AdoptiveParentsComponent }, diff --git a/web/src/app/route-components/adoption/adoption.component.html b/web/src/app/route-components/adoption/adoption.component.html new file mode 100644 index 00000000..2a879b6d --- /dev/null +++ b/web/src/app/route-components/adoption/adoption.component.html @@ -0,0 +1,43 @@ + + +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + +
    +
    +
    + + + + +
    \ No newline at end of file diff --git a/web/src/app/route-components/adoption/adoption.component.scss b/web/src/app/route-components/adoption/adoption.component.scss new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/adoption/adoption.component.spec.ts b/web/src/app/route-components/adoption/adoption.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/web/src/app/route-components/adoption/adoption.component.ts b/web/src/app/route-components/adoption/adoption.component.ts new file mode 100644 index 00000000..71921f37 --- /dev/null +++ b/web/src/app/route-components/adoption/adoption.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { BaseComponent } from 'src/app/utils-components/base/base.component'; +import { Validators, FormBuilder, FormGroup } from '@angular/forms'; +import { FoiRequest } from 'src/app/models/FoiRequest'; +import { DataService } from 'src/app/services/data.service'; + + +@Component({ + templateUrl: './adoption.component.html', + styleUrls: ['./adoption.component.scss'] +}) +export class Adoption implements OnInit { + + @ViewChild(BaseComponent) base: BaseComponent; + + foiForm = this.fb.group({ + adoptionselection: [null, [Validators.required]] + }); + + foiRequest: FoiRequest; + targetKey: string = "adoption"; + + constructor(private fb: FormBuilder, private dataService: DataService) {} + + ngOnInit() { + + + // Load the current values & populate the FormGroup. + this.foiRequest = this.dataService.getCurrentState(this.targetKey); + this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + } + + doContinue() { + + const formData = this.foiForm.value; + + + // Update save data & proceed. + this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); + this.base.goFoiForward(); + } + + doGoBack() { + this.base.goFoiBack(); + } + + +} diff --git a/web/src/app/route-components/route-components.module.ts b/web/src/app/route-components/route-components.module.ts index 16b45a90..1eb8bc1a 100644 --- a/web/src/app/route-components/route-components.module.ts +++ b/web/src/app/route-components/route-components.module.ts @@ -21,6 +21,7 @@ import { ChildProtectionChild } from './childprotection-child/childprotection-ch import { YouthInCareParent } from './youthincare-parent/youthincare-parent.component'; import { YouthInCareChild } from './youthincare-child/youthincare-child.component'; import { FosterParent } from './foster-parent/foster-parent.component'; +import { Adoption } from './adoption/adoption.component'; import { ContactInfoOptionsComponent } from './contact-info-options/contact-info-options.component'; import { ProofOfGuardianshipComponent } from './proof-of-guardianship/proof-of-guardianship.component'; import { ChildInformationComponent } from './child-information/child-information.component'; @@ -62,6 +63,7 @@ library.add(faSpinner); YouthInCareParent, YouthInCareChild, FosterParent, + Adoption, ContactInfoOptionsComponent, ProofOfGuardianshipComponent, ChildInformationComponent, From 4965ad2e46dffbef086d5a36bc346bfcb1816caa Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Tue, 4 Oct 2022 15:46:34 -0700 Subject: [PATCH 244/589] #2861 removed child in care --- web/src/app/services/data.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/web/src/app/services/data.json b/web/src/app/services/data.json index 922ef5d7..112de918 100644 --- a/web/src/app/services/data.json +++ b/web/src/app/services/data.json @@ -51,11 +51,7 @@ "text": "Your income assistance history", "ministryCode": "SDPR" }, - { - "value": "childProtection", - "text": "Child protection and youth care", - "ministryCode": "MCF" - }, + { "value": "adoption", "text": "Adoption", "ministryCode": "MCF" }, { "value": "anotherTopic", "text": "Other", "ministryCode": null } ], From 69360027adb800fee93d2ee7248352e2e4ee2489 Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Wed, 5 Oct 2022 12:33:27 -0700 Subject: [PATCH 245/589] WIP #2861 --- web/src/app/app-routing.module.ts | 45 ++- .../childprotection-parent.component.html | 88 ++++++ .../childprotection-parent.component.scss | 15 + .../youthincare-child.component.html | 274 +++++++++++++++++- .../youthincare-child.component.scss | 15 + .../youthincare-child.component.ts | 57 +++- web/src/app/services/data.json | 114 +++++--- web/src/app/services/data.service.ts | 4 + 8 files changed, 546 insertions(+), 66 deletions(-) diff --git a/web/src/app/app-routing.module.ts b/web/src/app/app-routing.module.ts index e9ed8ba8..ec0d6df0 100644 --- a/web/src/app/app-routing.module.ts +++ b/web/src/app/app-routing.module.ts @@ -65,12 +65,55 @@ const routes: Routes = [ { path: 'personal/youthincarechild', component: YouthInCareChild }, { path: 'personal/fosterparent', component: FosterParent }, { path: 'personal/adoption', component: Adoption }, + { path: 'personal/ministry-confirmation', component: MinistryConfirmationComponent }, - { path: 'personal/description-timeframe', component: DescriptionTimeframeComponent }, + { path: 'personal/youthincarechild/ministry-confirmation', component: MinistryConfirmationComponent }, + { path: 'personal/childprotectionparent/ministry-confirmation', component: MinistryConfirmationComponent }, + { path: 'personal/childprotectionchild/ministry-confirmation', component: MinistryConfirmationComponent }, + { path: 'personal/youthincareparent/ministry-confirmation', component: MinistryConfirmationComponent }, + { path: 'personal/fosterparent/ministry-confirmation', component: MinistryConfirmationComponent }, + { path: 'personal/adoption/ministry-confirmation', component: MinistryConfirmationComponent }, + + { path: 'personal/youthincarechild/description-timeframe', component: DescriptionTimeframeComponent }, + { path: 'personal/description-timeframe', component: DescriptionTimeframeComponent }, + { path: 'personal/childprotectionparent/description-timeframe', component: DescriptionTimeframeComponent }, + { path: 'personal/childprotectionchild/description-timeframe', component: DescriptionTimeframeComponent }, + { path: 'personal/youthincareparent/description-timeframe', component: DescriptionTimeframeComponent }, + { path: 'personal/fosterparent/description-timeframe', component: DescriptionTimeframeComponent }, + { path: 'personal/adoption/description-timeframe', component: DescriptionTimeframeComponent }, + { path: 'personal/adoptive-parents', component: AdoptiveParentsComponent }, + { path: 'personal/youthincarechild/adoptive-parents', component: AdoptiveParentsComponent }, + { path: 'personal/childprotectionparent/adoptive-parents', component: AdoptiveParentsComponent }, + { path: 'personal/childprotectionparent/adoptive-parents', component: AdoptiveParentsComponent }, + { path: 'personal/youthincareparent/adoptive-parents', component: AdoptiveParentsComponent }, + { path: 'personal/fosterparent/adoptive-parents', component: AdoptiveParentsComponent }, + { path: 'personal/adoption/adoptive-parents', component: AdoptiveParentsComponent }, + { path: 'personal/contact-info-options', component: ContactInfoOptionsComponent }, + { path: 'personal/youthincarechild/contact-info-options', component: ContactInfoOptionsComponent }, + { path: 'personal/childprotectionparent/contact-info-options', component: ContactInfoOptionsComponent }, + { path: 'personal/childprotectionparent/contact-info-options', component: ContactInfoOptionsComponent }, + { path: 'personal/youthincareparent/contact-info-options', component: ContactInfoOptionsComponent }, + { path: 'personal/fosterparent/contact-info-options', component: ContactInfoOptionsComponent }, + { path: 'personal/adoption/contact-info-options', component: ContactInfoOptionsComponent }, + + { path: 'personal/review-submit', component: ReviewSubmitComponent }, + { path: 'personal/youthincarechild/review-submit', component: ReviewSubmitComponent }, + { path: 'personal/childprotectionparent/review-submit', component: ReviewSubmitComponent }, + { path: 'personal/childprotectionparent/review-submit', component: ReviewSubmitComponent }, + { path: 'personal/youthincareparent/review-submit', component: ReviewSubmitComponent }, + { path: 'personal/fosterparent/review-submit', component: ReviewSubmitComponent }, + { path: 'personal/adoption/review-submit', component: ReviewSubmitComponent }, + { path: 'personal/submit-complete', component: ReviewSubmitCompleteComponent}, + { path: 'personal/youthincarechild/submit-complete', component: ReviewSubmitCompleteComponent }, + { path: 'personal/childprotectionparent/submit-complete', component: ReviewSubmitCompleteComponent }, + { path: 'personal/childprotectionparent/submit-complete', component: ReviewSubmitCompleteComponent }, + { path: 'personal/youthincareparent/submit-complete', component: ReviewSubmitCompleteComponent }, + { path: 'personal/fosterparent/submit-complete', component: ReviewSubmitCompleteComponent }, + { path: 'personal/adoption/submit-complete', component: ReviewSubmitCompleteComponent }, // Personal / Child { path: 'personal/child/proof-of-guardianship', component: ProofOfGuardianshipComponent }, diff --git a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html index c206f10f..9b1b0257 100644 --- a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html +++ b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html @@ -9,6 +9,94 @@ Child Protection Investigation Records (Family Service File) +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    + + +
    +
    diff --git a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.scss b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.scss index e69de29b..2365b06b 100644 --- a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.scss +++ b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.scss @@ -0,0 +1,15 @@ +.subgroup { + padding-left: 4%; + + .row { + .form-check-label { + font-size: 14px; + } + + .form-check-inline{ + padding-right: 5px; + } + + padding-top: 1%; + } +} \ No newline at end of file diff --git a/web/src/app/route-components/youthincare-child/youthincare-child.component.html b/web/src/app/route-components/youthincare-child/youthincare-child.component.html index 0264cd85..22db4566 100644 --- a/web/src/app/route-components/youthincare-child/youthincare-child.component.html +++ b/web/src/app/route-components/youthincare-child/youthincare-child.component.html @@ -2,47 +2,289 @@
    - +

    Youth in care - Child Submitting Request

    - +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    + +
    +
    - +
    +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    - +
    +
    + We do not hold these records. Your records can be requested  here +
    +
    diff --git a/web/src/app/route-components/youthincare-child/youthincare-child.component.scss b/web/src/app/route-components/youthincare-child/youthincare-child.component.scss index e69de29b..2365b06b 100644 --- a/web/src/app/route-components/youthincare-child/youthincare-child.component.scss +++ b/web/src/app/route-components/youthincare-child/youthincare-child.component.scss @@ -0,0 +1,15 @@ +.subgroup { + padding-left: 4%; + + .row { + .form-check-label { + font-size: 14px; + } + + .form-check-inline{ + padding-right: 5px; + } + + padding-top: 1%; + } +} \ No newline at end of file diff --git a/web/src/app/route-components/youthincare-child/youthincare-child.component.ts b/web/src/app/route-components/youthincare-child/youthincare-child.component.ts index 9f7e2e15..8559873a 100644 --- a/web/src/app/route-components/youthincare-child/youthincare-child.component.ts +++ b/web/src/app/route-components/youthincare-child/youthincare-child.component.ts @@ -14,29 +14,72 @@ export class YouthInCareChild implements OnInit { @ViewChild(BaseComponent) base: BaseComponent; foiForm = this.fb.group({ - youthincarechildselection: [null, [Validators.required]] + youthincarechildselection: [null, [Validators.required]], + ischildincardrecords:false, + ismentalhealthrecords:false, + isspecialneedsrecords:false, + isyouthagreement:false, + isyouthjustice:false, + isother:false, }); foiRequest: FoiRequest; targetKey: string = "youthincarechild"; + ischildincardrecords: boolean = false; // hidden by default + ismentalhealthrecords: boolean = false; // hidden by default + isspecialneedsrecords: boolean = false; // hidden by default + isyouthagreement: boolean = false; // hidden by default + isyouthjustice: boolean = false; // hidden by default + isother: boolean = false; // hidden by default - constructor(private fb: FormBuilder, private dataService: DataService) {} + constructor(private fb: FormBuilder, private dataService: DataService) { } ngOnInit() { - - + + console.log(this.dataService.getYouthinCareChild()) + // Load the current values & populate the FormGroup. - this.foiRequest = this.dataService.getCurrentState(this.targetKey); + this.foiRequest = this.dataService.getCurrentState(this.targetKey); this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + + this.ischildincardrecords = this.foiRequest.requestData[this.targetKey].ischildincardrecords; + this.ismentalhealthrecords = this.foiRequest.requestData[this.targetKey].ismentalhealthrecords; + this.isspecialneedsrecords = this.foiRequest.requestData[this.targetKey].isspecialneedsrecords; + this.isyouthagreement = this.foiRequest.requestData[this.targetKey].isyouthagreement; + this.isyouthjustice = this.foiRequest.requestData[this.targetKey].isyouthjustice; + this.isother= this.foiRequest.requestData[this.targetKey].isother; + } + + togglechildincardrecordsShow() { + this.ischildincardrecords = !this.ischildincardrecords; + } + + togglementalhealthrecordsShow() { + this.ismentalhealthrecords = !this.ismentalhealthrecords; + } + + toggleyouthagreementShow() { + this.isyouthagreement = !this.isyouthagreement; + } + + togglespecialneedsrecordsShow() { + this.isspecialneedsrecords = !this.isspecialneedsrecords; } doContinue() { const formData = this.foiForm.value; - + this.foiRequest.requestData[this.targetKey].ischildincardrecords = this.ischildincardrecords + this.foiRequest.requestData[this.targetKey].ismentalhealthrecords =this.ismentalhealthrecords; + this.foiRequest.requestData[this.targetKey].isyouthagreement =this.isyouthagreement; + this.foiRequest.requestData[this.targetKey].isspecialneedsrecords = this.isspecialneedsrecords; + this.foiRequest.requestData[this.targetKey].isyouthjustice = this.isyouthjustice; + this.foiRequest.requestData[this.targetKey].isother = this.isother; // Update save data & proceed. this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); + console.log(`Key ${JSON.stringify(this.foiRequest.requestData[this.targetKey])}`); + this.base.goFoiForward(); } @@ -44,5 +87,5 @@ export class YouthInCareChild implements OnInit { this.base.goFoiBack(); } - + } diff --git a/web/src/app/services/data.json b/web/src/app/services/data.json index 112de918..633ac834 100644 --- a/web/src/app/services/data.json +++ b/web/src/app/services/data.json @@ -30,11 +30,7 @@ { "code": "TRAN", "name": "Transportation and Infrastructure", "publicBody": "Transportation and Infrastructure" } ], "topicYourself": [ - { "value": "childprotectionparent", "text": "Child protection – Parent Submitting Request", "ministryCode": "MCF" }, - { "value": "childprotectionchild", "text": "Child protection – Child Submitting Request", "ministryCode": "MCF" }, - { "value": "youthincareparent", "text": "Youth in care - Parent Submitting Request", "ministryCode": "MCF" }, - { "value": "youthincarechild", "text": "Youth in care - Child Submitting Request", "ministryCode": "MCF" }, - { "value": "fosterparent", "text": "Foster Parent", "ministryCode": "MCF" }, + { "value": "publicServiceEmployment", @@ -51,7 +47,11 @@ "text": "Your income assistance history", "ministryCode": "SDPR" }, - + { "value": "childprotectionparent", "text": "Child protection – Parent Submitting Request", "ministryCode": "MCF" }, + { "value": "childprotectionchild", "text": "Child protection – Child Submitting Request", "ministryCode": "MCF" }, + { "value": "youthincareparent", "text": "Youth in care - Parent Submitting Request", "ministryCode": "MCF" }, + { "value": "youthincarechild", "text": "Youth in care - Child Submitting Request", "ministryCode": "MCF" }, + { "value": "fosterparent", "text": "Foster Parent", "ministryCode": "MCF" }, { "value": "adoption", "text": "Adoption", "ministryCode": "MCF" }, { "value": "anotherTopic", "text": "Other", "ministryCode": null } ], @@ -112,6 +112,36 @@ }, { "value": "adoption", "text": "Adoption", "ministryCode": "MCF" }, { "value": "anotherTopic", "text": "Other", "ministryCode": null } + ], + "youthincarechild":[ + { "main":"Child in Card Records" , "suboptions":[ + {"option":"Personal History, Recordings & Service Plans"}, + {"option":"Cultural Planning / Roots"}, + {"option":"Legal & Agreements"}, + {"option":"Financial Documentation"}, + {"option":"External Assessment & Reports"}, + {"option":"Medical"}, + {"option":"Internal Assessments"}, + {"option":"Reviews"}, + {"option":"Adoption"}, + {"option":"Out of Care Services"}, + {"option":"General Correspondence"}, + {"option":"Collaborative Planning & Decisions Making"}, + {"option":"Education, Employment & Training"}, + {"option":"Practitioner Case Notes"} + + ] }, + { + "main":"Child in Youth Mental Health Records " ,"suboptions":[ + {"option":"Clinical History"}, + {"option":"Complex Care Intervention"}, + {"option":"Assessment & Reports"}, + {"option":"Psychological Test Protocols & Rough Notes"}, + {"option":"Clinician’s Standardized Questionnaires & Rough Notes"}, + {"option":"Artwork & Photos"}, + {"option":"Child & Youth Mental Health Case Files "} + ] + } ] }, "routeTree": [ @@ -176,68 +206,68 @@ "routes":[ { "route": "personal/childprotectionparent","progress": 2}, - { "route": "personal/ministry-confirmation","progress": 2}, - {"route": "personal/description-timeframe","progress": 2}, - { "route": "personal/adoptive-parents","progress": 3}, - {"route": "personal/contact-info-options","progress": 3}, - { "route": "personal/review-submit", "progress": 4 }, - { "route": "personal/submit-complete", "progress": 6 } + { "route": "personal/childprotectionparent/ministry-confirmation","progress": 2}, + {"route": "personal/childprotectionparent/description-timeframe","progress": 2}, + { "route": "personal/childprotectionparent/adoptive-parents","progress": 3}, + {"route": "personal/childprotectionparent/contact-info-options","progress": 3}, + { "route": "personal/childprotectionparent/review-submit", "progress": 4 }, + { "route": "personal/childprotectionparent/submit-complete", "progress": 6 } ] }, "childprotectionchild":{ "routes":[ { "route": "personal/childprotectionchild","progress": 2}, - { "route": "personal/ministry-confirmation","progress": 2}, - {"route": "personal/description-timeframe","progress": 2}, - { "route": "personal/adoptive-parents","progress": 3}, - {"route": "personal/contact-info-options","progress": 3}, - { "route": "personal/review-submit", "progress": 4 }, - { "route": "personal/submit-complete", "progress": 6 } + { "route": "personal/childprotectionchild/ministry-confirmation","progress": 2}, + {"route": "personal/childprotectionchild/description-timeframe","progress": 2}, + { "route": "personal/childprotectionchild/adoptive-parents","progress": 3}, + {"route": "personal/childprotectionchild/contact-info-options","progress": 3}, + { "route": "personal/childprotectionchild/review-submit", "progress": 4 }, + { "route": "personal/childprotectionchild/submit-complete", "progress": 6 } ] }, "youthincareparent":{ "routes":[ { "route": "personal/youthincareparent","progress": 2}, - { "route": "personal/ministry-confirmation","progress": 2}, - {"route": "personal/description-timeframe","progress": 2}, - { "route": "personal/adoptive-parents","progress": 3}, - {"route": "personal/contact-info-options","progress": 3}, - { "route": "personal/review-submit", "progress": 4 }, - { "route": "personal/submit-complete", "progress": 6 } + { "route": "personal/youthincareparent/ministry-confirmation","progress": 2}, + {"route": "personal/youthincareparent/description-timeframe","progress": 2}, + { "route": "personal/youthincareparent/adoptive-parents","progress": 3}, + {"route": "personal/youthincareparent/contact-info-options","progress": 3}, + { "route": "personal/youthincareparent/review-submit", "progress": 4 }, + { "route": "personal/youthincareparent/submit-complete", "progress": 6 } ]}, "youthincarechild":{ "routes":[ { "route": "personal/youthincarechild","progress": 2}, - { "route": "personal/ministry-confirmation","progress": 2}, - {"route": "personal/description-timeframe","progress": 2}, - { "route": "personal/adoptive-parents","progress": 3}, - {"route": "personal/contact-info-options","progress": 3}, - { "route": "personal/review-submit", "progress": 4 }, - { "route": "personal/submit-complete", "progress": 6 } + { "route": "personal/youthincarechild/ministry-confirmation","progress": 3}, + {"route": "personal/youthincarechild/description-timeframe","progress": 2}, + { "route": "personal/youthincarechild/adoptive-parents","progress": 3}, + {"route": "personal/youthincarechild/contact-info-options","progress": 3}, + { "route": "personal/youthincarechild/review-submit", "progress": 4 }, + { "route": "personal/youthincarechild/submit-complete", "progress": 6 } ]}, "fosterparent":{ "routes":[ { "route": "personal/fosterparent","progress": 2}, - { "route": "personal/ministry-confirmation","progress": 2}, - {"route": "personal/description-timeframe","progress": 2}, - { "route": "personal/adoptive-parents","progress": 3}, - {"route": "personal/contact-info-options","progress": 3}, - { "route": "personal/review-submit", "progress": 4 }, - { "route": "personal/submit-complete", "progress": 6 } + { "route": "personal/fosterparent/ministry-confirmation","progress": 2}, + {"route": "personal/fosterparent/description-timeframe","progress": 2}, + { "route": "personal/fosterparent/adoptive-parents","progress": 3}, + {"route": "personal/fosterparent/contact-info-options","progress": 3}, + { "route": "personal/fosterparent/review-submit", "progress": 4 }, + { "route": "personal/fosterparent/submit-complete", "progress": 6 } ]}, "adoption":{ "routes":[ { "route": "personal/adoption","progress": 2}, - { "route": "personal/ministry-confirmation","progress": 2}, - {"route": "personal/description-timeframe","progress": 2}, - { "route": "personal/adoptive-parents","progress": 3}, - {"route": "personal/contact-info-options","progress": 3}, - { "route": "personal/review-submit", "progress": 4 }, - { "route": "personal/submit-complete", "progress": 6 } + { "route": "personal/adoption/ministry-confirmation","progress": 2}, + {"route": "personal/adoption/description-timeframe","progress": 2}, + { "route": "personal/adoption/adoptive-parents","progress": 3}, + {"route": "personal/adoption/contact-info-options","progress": 3}, + { "route": "personal/adoption/review-submit", "progress": 4 }, + { "route": "personal/adoption/submit-complete", "progress": 6 } ]}, diff --git a/web/src/app/services/data.service.ts b/web/src/app/services/data.service.ts index 83e50556..b1c85e4d 100644 --- a/web/src/app/services/data.service.ts +++ b/web/src/app/services/data.service.ts @@ -38,6 +38,10 @@ export class DataService { return of(data.referenceData.ministries); } + getYouthinCareChild(): Observable { + return of(data.referenceData.youthincarechild); + } + capitalize(str) { if (typeof str !== "string") { return ""; From a99d41ac282c9d1d06b7b13bf2648d9f9df7a537 Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Wed, 5 Oct 2022 17:32:30 -0700 Subject: [PATCH 246/589] #2861 --- .../youthincare-child.component.html | 293 +----------------- .../youthincare-child.component.ts | 71 +++-- web/src/app/services/data.json | 36 ++- 3 files changed, 88 insertions(+), 312 deletions(-) diff --git a/web/src/app/route-components/youthincare-child/youthincare-child.component.html b/web/src/app/route-components/youthincare-child/youthincare-child.component.html index 22db4566..851f850c 100644 --- a/web/src/app/route-components/youthincare-child/youthincare-child.component.html +++ b/web/src/app/route-components/youthincare-child/youthincare-child.component.html @@ -4,290 +4,29 @@

    Youth in care - Child Submitting Request

    -
    - -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    -
    - -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - - -
    -
    - - -
    -
    -
    -
    -
    - -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    +
    +
    + +
    +
    -
    +
    + + +
    -
    -
    -
    - -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    - - -
    -
    -
    -
    -
    - -
    -
    - We do not hold these records. Your records can be requested  here +
    -
    - -
    diff --git a/web/src/app/route-components/youthincare-child/youthincare-child.component.ts b/web/src/app/route-components/youthincare-child/youthincare-child.component.ts index 8559873a..84b7ffa6 100644 --- a/web/src/app/route-components/youthincare-child/youthincare-child.component.ts +++ b/web/src/app/route-components/youthincare-child/youthincare-child.component.ts @@ -3,8 +3,9 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { Validators, FormBuilder, FormGroup } from '@angular/forms'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { DataService } from 'src/app/services/data.service'; - - +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +import { ContactInfoOptionsComponent } from '../contact-info-options/contact-info-options.component'; @Component({ templateUrl: './youthincare-child.component.html', styleUrls: ['./youthincare-child.component.scss'] @@ -20,65 +21,69 @@ export class YouthInCareChild implements OnInit { isspecialneedsrecords:false, isyouthagreement:false, isyouthjustice:false, - isother:false, + isother:false + }); foiRequest: FoiRequest; targetKey: string = "youthincarechild"; - ischildincardrecords: boolean = false; // hidden by default - ismentalhealthrecords: boolean = false; // hidden by default - isspecialneedsrecords: boolean = false; // hidden by default - isyouthagreement: boolean = false; // hidden by default - isyouthjustice: boolean = false; // hidden by default - isother: boolean = false; // hidden by default + + youthincareoptions: Observable; + mainoptions:Array; constructor(private fb: FormBuilder, private dataService: DataService) { } ngOnInit() { - console.log(this.dataService.getYouthinCareChild()) + + + //console.log(JSON.stringify(this.youthincareoptions)) // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); - this.ischildincardrecords = this.foiRequest.requestData[this.targetKey].ischildincardrecords; - this.ismentalhealthrecords = this.foiRequest.requestData[this.targetKey].ismentalhealthrecords; - this.isspecialneedsrecords = this.foiRequest.requestData[this.targetKey].isspecialneedsrecords; - this.isyouthagreement = this.foiRequest.requestData[this.targetKey].isyouthagreement; - this.isyouthjustice = this.foiRequest.requestData[this.targetKey].isyouthjustice; - this.isother= this.foiRequest.requestData[this.targetKey].isother; + let selectedyouthincare = this.foiRequest.requestData[this.targetKey].selectedyouthincare; + + this.youthincareoptions = this.dataService.getYouthinCareChild().pipe( + map(mainoptions=>{ + mainoptions.forEach(mainoption =>{ + mainoption.selected = mainoption.selected || (selectedyouthincare ? !! selectedyouthincare.find(ms => ms.selected === mainoption.selected) : false); + }) + + return mainoptions; + }), + map(mainoptions => { + this.mainoptions = mainoptions; + return mainoptions; + }) + ); + } - togglechildincardrecordsShow() { - this.ischildincardrecords = !this.ischildincardrecords; + showsubsection(item:any) + { + item.selected=!item.selected } - togglementalhealthrecordsShow() { - this.ismentalhealthrecords = !this.ismentalhealthrecords; - } + selectedsuboption(item:any) + { + item.selected=!item.selected - toggleyouthagreementShow() { - this.isyouthagreement = !this.isyouthagreement; } - togglespecialneedsrecordsShow() { - this.isspecialneedsrecords = !this.isspecialneedsrecords; - } + doContinue() { const formData = this.foiForm.value; - this.foiRequest.requestData[this.targetKey].ischildincardrecords = this.ischildincardrecords - this.foiRequest.requestData[this.targetKey].ismentalhealthrecords =this.ismentalhealthrecords; - this.foiRequest.requestData[this.targetKey].isyouthagreement =this.isyouthagreement; - this.foiRequest.requestData[this.targetKey].isspecialneedsrecords = this.isspecialneedsrecords; - this.foiRequest.requestData[this.targetKey].isyouthjustice = this.isyouthjustice; - this.foiRequest.requestData[this.targetKey].isother = this.isother; + let selected = this.mainoptions.filter(m => m.selected); + this.foiRequest.requestData[this.targetKey].selectedyouthincare = selected; + // Update save data & proceed. this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); - console.log(`Key ${JSON.stringify(this.foiRequest.requestData[this.targetKey])}`); + console.log(`Key ${JSON.stringify(selected)}`); this.base.goFoiForward(); } diff --git a/web/src/app/services/data.json b/web/src/app/services/data.json index 633ac834..7cc7e359 100644 --- a/web/src/app/services/data.json +++ b/web/src/app/services/data.json @@ -114,7 +114,7 @@ { "value": "anotherTopic", "text": "Other", "ministryCode": null } ], "youthincarechild":[ - { "main":"Child in Card Records" , "suboptions":[ + { "mainoption":"Child in Card Records" , "suboptions":[ {"option":"Personal History, Recordings & Service Plans"}, {"option":"Cultural Planning / Roots"}, {"option":"Legal & Agreements"}, @@ -132,7 +132,7 @@ ] }, { - "main":"Child in Youth Mental Health Records " ,"suboptions":[ + "mainoption":"Child in Youth Mental Health Records" ,"suboptions":[ {"option":"Clinical History"}, {"option":"Complex Care Intervention"}, {"option":"Assessment & Reports"}, @@ -141,6 +141,38 @@ {"option":"Artwork & Photos"}, {"option":"Child & Youth Mental Health Case Files "} ] + }, + { + "mainoption":"Child in Youth Special Needs Records" ,"suboptions":[ + {"option":"Personal History & Recording"}, + {"option":"Intake / Service Request & Memo"}, + {"option":"Legal and Financial Documentation "}, + {"option":"Reports"}, + {"option":"Correspondence"}, + {"option":"At Home Program Legal & Financial"}, + {"option":"Autism Funding"}, + {"option":"Respite Benefits"}, + {"option":"Practitioner Case Notes"} + ] + }, + { + "mainoption":"Youth Agreement" ,"suboptions":[ + {"option":"Personal History & Recordings"}, + {"option":"Service Request & Memo"}, + {"option":"Agreements"}, + {"option":"Reports"}, + {"option":"Financial Documentation"}, + {"option":"Program Planning Documentation"} + ] + }, + { + "mainoption":"Youth Justice" ,"suboptions":[ + {"option":"We do not hold these records. Your records can be requested here.","istext":true} + + ] + }, + { + "mainoption":"Other" ,"suboptions":[] } ] }, From 70fae6c1d80e44ab522eac1f15cb834e963a4e17 Mon Sep 17 00:00:00 2001 From: Abin Antony Date: Thu, 6 Oct 2022 14:38:08 -0700 Subject: [PATCH 247/589] #2861 Data JSOn updates and related UX --- .../adoption/adoption.component.html | 47 +++--- .../adoption/adoption.component.scss | 15 ++ .../adoption/adoption.component.ts | 36 ++++- .../childprotection-child.component.html | 33 +++-- .../childprotection-child.component.scss | 15 ++ .../childprotection-child.component.ts | 34 ++++- .../childprotection-parent.component.html | 117 +++------------ .../childprotection-parent.component.ts | 35 ++++- .../foster-parent.component.html | 40 +++--- .../foster-parent.component.scss | 15 ++ .../foster-parent/foster-parent.component.ts | 35 ++++- .../youthincare-parent.component.html | 35 +++-- .../youthincare-parent.component.scss | 15 ++ .../youthincare-parent.component.ts | 36 ++++- web/src/app/services/data.json | 136 ++++++++++++++++++ web/src/app/services/data.service.ts | 20 +++ 16 files changed, 488 insertions(+), 176 deletions(-) diff --git a/web/src/app/route-components/adoption/adoption.component.html b/web/src/app/route-components/adoption/adoption.component.html index 2a879b6d..c8f3cc0c 100644 --- a/web/src/app/route-components/adoption/adoption.component.html +++ b/web/src/app/route-components/adoption/adoption.component.html @@ -4,33 +4,28 @@
    -
    - -
    -
    - - -
    -
    - - -
    -
    - +
    +
    + +
    +
    + +
    + + +
    + +
    + +
    +
    diff --git a/web/src/app/route-components/adoption/adoption.component.scss b/web/src/app/route-components/adoption/adoption.component.scss index e69de29b..2365b06b 100644 --- a/web/src/app/route-components/adoption/adoption.component.scss +++ b/web/src/app/route-components/adoption/adoption.component.scss @@ -0,0 +1,15 @@ +.subgroup { + padding-left: 4%; + + .row { + .form-check-label { + font-size: 14px; + } + + .form-check-inline{ + padding-right: 5px; + } + + padding-top: 1%; + } +} \ No newline at end of file diff --git a/web/src/app/route-components/adoption/adoption.component.ts b/web/src/app/route-components/adoption/adoption.component.ts index 71921f37..81c6159c 100644 --- a/web/src/app/route-components/adoption/adoption.component.ts +++ b/web/src/app/route-components/adoption/adoption.component.ts @@ -3,7 +3,8 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { Validators, FormBuilder, FormGroup } from '@angular/forms'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { DataService } from 'src/app/services/data.service'; - +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; @Component({ templateUrl: './adoption.component.html', @@ -19,6 +20,8 @@ export class Adoption implements OnInit { foiRequest: FoiRequest; targetKey: string = "adoption"; + fulllistoptions: Observable; + mainoptions:Array; constructor(private fb: FormBuilder, private dataService: DataService) {} @@ -28,13 +31,42 @@ export class Adoption implements OnInit { // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + + + let selectedoptions = this.foiRequest.requestData[this.targetKey].selectedoptions; + + this.fulllistoptions = this.dataService.getAdoptionData().pipe( + map(mainoptions=>{ + mainoptions.forEach(mainoption =>{ + mainoption.selected = mainoption.selected || (selectedoptions ? !! selectedoptions.find(ms => ms.selected === mainoption.selected) : false); + }) + + return mainoptions; + }), + map(mainoptions => { + this.mainoptions = mainoptions; + return mainoptions; + }) + ); + } + + showsubsection(item:any) + { + item.selected=!item.selected + } + + selectedsuboption(item:any) + { + item.selected=!item.selected + } doContinue() { const formData = this.foiForm.value; - + let selected = this.mainoptions.filter(m => m.selected); + this.foiRequest.requestData[this.targetKey].selectedoptions = selected; // Update save data & proceed. this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); this.base.goFoiForward(); diff --git a/web/src/app/route-components/childprotection-child/childprotection-child.component.html b/web/src/app/route-components/childprotection-child/childprotection-child.component.html index 5997cd4a..c8f3cc0c 100644 --- a/web/src/app/route-components/childprotection-child/childprotection-child.component.html +++ b/web/src/app/route-components/childprotection-child/childprotection-child.component.html @@ -4,19 +4,28 @@
    -
    - -
    -
    - +
    +
    + +
    +
    + +
    + + +
    + +
    + +
    +
    diff --git a/web/src/app/route-components/childprotection-child/childprotection-child.component.scss b/web/src/app/route-components/childprotection-child/childprotection-child.component.scss index e69de29b..2365b06b 100644 --- a/web/src/app/route-components/childprotection-child/childprotection-child.component.scss +++ b/web/src/app/route-components/childprotection-child/childprotection-child.component.scss @@ -0,0 +1,15 @@ +.subgroup { + padding-left: 4%; + + .row { + .form-check-label { + font-size: 14px; + } + + .form-check-inline{ + padding-right: 5px; + } + + padding-top: 1%; + } +} \ No newline at end of file diff --git a/web/src/app/route-components/childprotection-child/childprotection-child.component.ts b/web/src/app/route-components/childprotection-child/childprotection-child.component.ts index b20574d1..79d0270d 100644 --- a/web/src/app/route-components/childprotection-child/childprotection-child.component.ts +++ b/web/src/app/route-components/childprotection-child/childprotection-child.component.ts @@ -3,7 +3,8 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { Validators, FormBuilder, FormGroup } from '@angular/forms'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { DataService } from 'src/app/services/data.service'; - +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; @Component({ templateUrl: './childprotection-child.component.html', @@ -19,6 +20,8 @@ export class ChildProtectionChild implements OnInit { foiRequest: FoiRequest; targetKey: string = "childprotectionchild"; + fulllistoptions: Observable; + mainoptions:Array; constructor(private fb: FormBuilder, private dataService: DataService) {} @@ -28,12 +31,41 @@ export class ChildProtectionChild implements OnInit { // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + + let selectedoptions = this.foiRequest.requestData[this.targetKey].selectedoptions; + + this.fulllistoptions = this.dataService.getChildInProtectionChild().pipe( + map(mainoptions=>{ + mainoptions.forEach(mainoption =>{ + mainoption.selected = mainoption.selected || (selectedoptions ? !! selectedoptions.find(ms => ms.selected === mainoption.selected) : false); + }) + + return mainoptions; + }), + map(mainoptions => { + this.mainoptions = mainoptions; + return mainoptions; + }) + ); + } + + showsubsection(item:any) + { + item.selected=!item.selected + } + + selectedsuboption(item:any) + { + item.selected=!item.selected + } doContinue() { const formData = this.foiForm.value; + let selected = this.mainoptions.filter(m => m.selected); + this.foiRequest.requestData[this.targetKey].selectedoptions = selected; // Update save data & proceed. this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); diff --git a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html index 9b1b0257..c8f3cc0c 100644 --- a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html +++ b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.html @@ -4,107 +4,28 @@
    -
    - -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    -
    -
    - - -
    -
    - - -
    -
    - - + +
    +
    + +
    +
    + +
    + + +
    +
    - - +
    - -
    -
    -
    diff --git a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.ts b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.ts index a414b582..0ca2bb9d 100644 --- a/web/src/app/route-components/childprotection-parent/childprotection-parent.component.ts +++ b/web/src/app/route-components/childprotection-parent/childprotection-parent.component.ts @@ -3,7 +3,8 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { Validators, FormBuilder, FormGroup } from '@angular/forms'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { DataService } from 'src/app/services/data.service'; - +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; @Component({ templateUrl: './childprotection-parent.component.html', @@ -19,7 +20,8 @@ export class ChildProtectionParent implements OnInit { foiRequest: FoiRequest; targetKey: string = "childprotectionparent"; - + fulllistoptions: Observable; + mainoptions:Array; constructor(private fb: FormBuilder, private dataService: DataService) {} ngOnInit() { @@ -28,13 +30,40 @@ export class ChildProtectionParent implements OnInit { // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + let selectedoptions = this.foiRequest.requestData[this.targetKey].selectedoptions; + + this.fulllistoptions = this.dataService.getChildInProtectionParent().pipe( + map(mainoptions=>{ + mainoptions.forEach(mainoption =>{ + mainoption.selected = mainoption.selected || (selectedoptions ? !! selectedoptions.find(ms => ms.selected === mainoption.selected) : false); + }) + + return mainoptions; + }), + map(mainoptions => { + this.mainoptions = mainoptions; + return mainoptions; + }) + ); + } + + showsubsection(item:any) + { + item.selected=!item.selected + } + + selectedsuboption(item:any) + { + item.selected=!item.selected + } doContinue() { const formData = this.foiForm.value; - + let selected = this.mainoptions.filter(m => m.selected); + this.foiRequest.requestData[this.targetKey].selectedoptions = selected; // Update save data & proceed. this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); this.base.goFoiForward(); diff --git a/web/src/app/route-components/foster-parent/foster-parent.component.html b/web/src/app/route-components/foster-parent/foster-parent.component.html index 1dea0efd..c8f3cc0c 100644 --- a/web/src/app/route-components/foster-parent/foster-parent.component.html +++ b/web/src/app/route-components/foster-parent/foster-parent.component.html @@ -4,26 +4,28 @@
    -
    - -
    -
    - - -
    -
    - +
    +
    + +
    +
    + +
    + + +
    + +
    + +
    +
    diff --git a/web/src/app/route-components/foster-parent/foster-parent.component.scss b/web/src/app/route-components/foster-parent/foster-parent.component.scss index e69de29b..2365b06b 100644 --- a/web/src/app/route-components/foster-parent/foster-parent.component.scss +++ b/web/src/app/route-components/foster-parent/foster-parent.component.scss @@ -0,0 +1,15 @@ +.subgroup { + padding-left: 4%; + + .row { + .form-check-label { + font-size: 14px; + } + + .form-check-inline{ + padding-right: 5px; + } + + padding-top: 1%; + } +} \ No newline at end of file diff --git a/web/src/app/route-components/foster-parent/foster-parent.component.ts b/web/src/app/route-components/foster-parent/foster-parent.component.ts index f90fafb0..306b339b 100644 --- a/web/src/app/route-components/foster-parent/foster-parent.component.ts +++ b/web/src/app/route-components/foster-parent/foster-parent.component.ts @@ -3,7 +3,8 @@ import { BaseComponent } from 'src/app/utils-components/base/base.component'; import { Validators, FormBuilder, FormGroup } from '@angular/forms'; import { FoiRequest } from 'src/app/models/FoiRequest'; import { DataService } from 'src/app/services/data.service'; - +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; @Component({ templateUrl: './foster-parent.component.html', @@ -19,6 +20,8 @@ export class FosterParent implements OnInit { foiRequest: FoiRequest; targetKey: string = "fosterparent"; + fulllistoptions: Observable; + mainoptions:Array; constructor(private fb: FormBuilder, private dataService: DataService) {} @@ -28,12 +31,42 @@ export class FosterParent implements OnInit { // Load the current values & populate the FormGroup. this.foiRequest = this.dataService.getCurrentState(this.targetKey); this.foiForm.patchValue(this.foiRequest.requestData[this.targetKey]); + + let selectedoptions = this.foiRequest.requestData[this.targetKey].selectedoptions; + + this.fulllistoptions = this.dataService.getFosterParent().pipe( + map(mainoptions=>{ + mainoptions.forEach(mainoption =>{ + mainoption.selected = mainoption.selected || (selectedoptions ? !! selectedoptions.find(ms => ms.selected === mainoption.selected) : false); + }) + + return mainoptions; + }), + map(mainoptions => { + this.mainoptions = mainoptions; + return mainoptions; + }) + ); + } + showsubsection(item:any) + { + item.selected=!item.selected + } + + selectedsuboption(item:any) + { + item.selected=!item.selected + + } + doContinue() { const formData = this.foiForm.value; + let selected = this.mainoptions.filter(m => m.selected); + this.foiRequest.requestData[this.targetKey].selectedoptions = selected; // Update save data & proceed. this.dataService.setCurrentState(this.foiRequest, this.targetKey, this.foiForm); diff --git a/web/src/app/route-components/youthincare-parent/youthincare-parent.component.html b/web/src/app/route-components/youthincare-parent/youthincare-parent.component.html index 57884311..c0ec6560 100644 --- a/web/src/app/route-components/youthincare-parent/youthincare-parent.component.html +++ b/web/src/app/route-components/youthincare-parent/youthincare-parent.component.html @@ -2,23 +2,32 @@
    -
    -
    - -
    -
    - +
    +
    + +
    +
    + +
    + + +
    + +
    + +
    +
    +