Implement test connection to Xero

This commit is contained in:
Rene Vergara 2022-08-09 17:23:58 -05:00
parent eb903b5ee3
commit 451bf6745c
Signed by: pitmutt
GPG key ID: 65122AD495A7F5B2
10 changed files with 1521 additions and 96 deletions

1416
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -34,10 +34,12 @@
"material-design-icons": "^3.0.1",
"mongoose": "^6.0.13",
"rxjs": "~6.6.0",
"sha.js": "^2.4.11",
"stdrpc": "^1.3.0",
"tslib": "^2.3.0",
"urlsafe-base64": "^1.0.0",
"uuid": "^8.3.2",
"xero-node": "^4.23.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
@ -46,6 +48,7 @@
"@angular/compiler-cli": "^14.0.5",
"@types/jasmine": "~3.8.0",
"@types/node": "^12.20.33",
"@types/request": "^2.48.8",
"@types/urlsafe-base64": "^1.0.28",
"@types/uuid": "^8.3.1",
"jasmine-core": "~3.8.0",

View file

@ -9,6 +9,7 @@ import { ListOrdersComponent } from './listorders/listorders.component';
import { AuthGuardService } from './auth-guard.service';
import { NodeResolverService } from './node-resolver.service';
import { PmtserviceComponent } from './pmtservice/pmtservice.component';
import { XeroRegComponent } from './xeroreg/xeroreg.component';
const routes: Routes = [
{ path: '', component: LoginComponent, resolve: { response: NodeResolverService} },
@ -19,6 +20,7 @@ const routes: Routes = [
{ path: 'receipt/:orderId', component: ReceiptComponent},
{ path: 'invoice/:orderId', component: InvoiceComponent},
{ path: 'pmtservice', component: PmtserviceComponent},
{ path: 'test', component: XeroRegComponent},
{ path: 'login', component: LoginComponent, resolve: { response: NodeResolverService}}
];

View file

@ -17,6 +17,7 @@ import { MatProgressBarModule } from '@angular/material/progress-bar';
import { MatStepperModule } from '@angular/material/stepper';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatTabsModule } from '@angular/material/tabs';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
@ -46,6 +47,7 @@ import { PromptInvoiceComponent } from './prompt-invoice/prompt-invoice.componen
import { PromptReceiptComponent } from './prompt-receipt/prompt-receipt.component';
import { NotifierComponent } from './notifier/notifier.component';
import { PmtserviceComponent } from './pmtservice/pmtservice.component';
import { XeroRegComponent } from './xeroreg/xeroreg.component';
@NgModule({
declarations: [
@ -73,7 +75,8 @@ import { PmtserviceComponent } from './pmtservice/pmtservice.component';
PromptInvoiceComponent,
PromptReceiptComponent,
NotifierComponent,
PmtserviceComponent
PmtserviceComponent,
XeroRegComponent
],
imports: [
BrowserModule,
@ -96,6 +99,7 @@ import { PmtserviceComponent } from './pmtservice/pmtservice.component';
MatAutocompleteModule,
MatSlideToggleModule,
MatSnackBarModule,
MatTabsModule,
BrowserAnimationsModule,
FontAwesomeModule
],

View file

@ -2,55 +2,64 @@
<div class="settings-title">Settings</div>
<div class="container" style="margin-top: 10px;">
<mat-dialog-content [formGroup]="settingsForm">
<mat-form-field class="settings-field" [style.width.%]="100">
<mat-label>Name</mat-label>
<input matInput
width="100%"
placeholder="Name"
formControlName="name">
</mat-form-field>
<mat-form-field [style.width.%]="100" >
<mat-label>Currency</mat-label>
<mat-select formControlName="currency">
<mat-option *ngFor="let coin of coins"
[value]="coin.symbol">
{{coin.label}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-slide-toggle formControlName="useZats"
class="settings-toggle"
(change)="onChange($event)">
Use zatoshis?
</mat-slide-toggle>
<pre></pre>
<mat-slide-toggle formControlName="useVKey"
class="settings-toggle"
(change)="onChangeVKeyOn($event)">
Confirm payments?
</mat-slide-toggle>
<pre></pre>
<mat-form-field [style.width.%]="100">
<mat-label>Viewing key</mat-label>
<input matInput placeholder="Your wallet viewing key"
formControlName="vKey">
</mat-form-field>
<mat-tab-group mat-tab-align-tabs="start">
<mat-tab label="Main">
<mat-dialog-content [formGroup]="settingsForm">
<mat-form-field class="settings-field" [style.width.%]="100">
<mat-label>Name</mat-label>
<input matInput
width="100%"
placeholder="Name"
formControlName="name">
</mat-form-field>
<mat-form-field [style.width.%]="100" >
<mat-label>Currency</mat-label>
<mat-select formControlName="currency">
<mat-option *ngFor="let coin of coins"
[value]="coin.symbol">
{{coin.label}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-slide-toggle formControlName="useZats"
class="settings-toggle"
(change)="onChange($event)">
Use zatoshis?
</mat-slide-toggle>
<pre></pre>
<mat-slide-toggle formControlName="useVKey"
class="settings-toggle"
(change)="onChangeVKeyOn($event)">
Confirm payments?
</mat-slide-toggle>
<pre></pre>
<mat-form-field [style.width.%]="100">
<mat-label>Viewing key</mat-label>
<input matInput placeholder="Your wallet viewing key"
formControlName="vKey">
</mat-form-field>
</mat-dialog-content>
</mat-dialog-content>
<mat-dialog-actions style="display: flex;
justify-content: space-between;
align-items: center;
margin-top: 12px;">
<button mat-raised-button
(click)="close()">
Cancel
</button>
<button mat-raised-button
color="primary"
(click)="save()">
Save
</button>
</mat-dialog-actions>
<mat-dialog-actions style="display: flex;
justify-content: space-between;
align-items: center;
margin-top: 12px;">
<button mat-raised-button
(click)="close()">
Cancel
</button>
<button mat-raised-button
color="primary"
(click)="save()">
Save
</button>
</mat-dialog-actions>
</mat-tab>
<mat-tab label="Advanced">
<a mat-raised-button color="primary" href="{{this.xeroLink}}">
Link to Xero
</a>
</mat-tab>
</mat-tab-group>
</div>

View file

@ -5,6 +5,10 @@ import { UntypedFormBuilder, Validators, UntypedFormGroup, FormControl } from '@
import { User } from '../user.model';
import { Owner } from '../owner.model';
var crypto = require('sha.js');
var URLSafeBase64 = require('urlsafe-base64');
var Buffer = require('buffer/').Buffer;
@Component({
selector: 'app-settings',
templateUrl: './settings.component.html',
@ -35,6 +39,8 @@ export class SettingsComponent implements OnInit {
symbol: 'aud'
}
];
xeroLink: string = '';
localToken: string = '';
constructor(
private fb: UntypedFormBuilder,
@ -56,6 +62,16 @@ export class SettingsComponent implements OnInit {
}
ngOnInit() {
this.localToken = localStorage.getItem('s4z_token')!;
const hash = crypto('sha256').update(this.owner.address).digest('base64');
//const hash2 = URLSafeBase64.encode(crypto('sha256').update(this.localToken));
console.log(hash);
console.log(this.safeURL(hash));
this.xeroLink = `https://login.xero.com/identity/connect/authorize?response_type=code&client_id=CA4A8C8DA0AE462186B34DBD42074D2D&redirect_uri=http%3A%2F%2Flocalhost%3A4200%2Ftest&scope=accounting.transactions offline_access&state=1234`
}
safeURL(s: string){
return s.replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
}
close() {

View file

View file

@ -0,0 +1 @@
<p>test works!</p>

View file

@ -0,0 +1,23 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { TestComponent } from './test.component';
describe('TestComponent', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ TestComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,43 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { HttpClient, HttpParams, HttpHeaders } from '@angular/common/http';
import { UserService } from '../user.service';
import { Owner } from '../owner.model';
//import { XeroClient } from 'xero-node';
var Buffer = require('buffer/').Buffer;
@Component({
selector: 'app-xeroreg',
templateUrl: './xeroreg.component.html',
styleUrls: ['./xeroreg.component.css']
})
export class XeroRegComponent implements OnInit {
reqHeaders: HttpHeaders;
constructor(private http: HttpClient,
private activatedRoute: ActivatedRoute
) {
//const secret = 'J8Ft70Tk6theIFNYpuDRPvzuc271_dyjq7EJlzPFh8lpXXvV';
var auth = 'Basic ' + Buffer.from('CA4A8C8DA0AE462186B34DBD42074D2D:J8Ft70Tk6theIFNYpuDRPvzuc271_dyjq7EJlzPFh8lpXXvV').toString('base64');
this.reqHeaders = new HttpHeaders().set('Authorization', auth).append('Content-Type', 'application/x-www-form-urlencoded');
//this.session = localStorage.getItem('s4z_token')!;
//this.ownerUpdate = userService.ownerUpdate;
//this.ownerUpdate.subscribe(ownerData => {
//this.owner = ownerData;
//});
}
ngOnInit(): void {
this.activatedRoute.queryParams.subscribe((params) => {
console.log(params);
this.http.post('https://identity.xero.com/connect/token', `grant_type=authorization_code&code=${params.code}&redirect_uri=http://localhost:4200/test` , {headers: this.reqHeaders, observe: 'response'})
.subscribe(responseData => {
console.log(responseData);
});
});
}
}