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

View file

@ -9,6 +9,7 @@ import { ListOrdersComponent } from './listorders/listorders.component';
import { AuthGuardService } from './auth-guard.service'; import { AuthGuardService } from './auth-guard.service';
import { NodeResolverService } from './node-resolver.service'; import { NodeResolverService } from './node-resolver.service';
import { PmtserviceComponent } from './pmtservice/pmtservice.component'; import { PmtserviceComponent } from './pmtservice/pmtservice.component';
import { XeroRegComponent } from './xeroreg/xeroreg.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', component: LoginComponent, resolve: { response: NodeResolverService} }, { path: '', component: LoginComponent, resolve: { response: NodeResolverService} },
@ -19,6 +20,7 @@ const routes: Routes = [
{ path: 'receipt/:orderId', component: ReceiptComponent}, { path: 'receipt/:orderId', component: ReceiptComponent},
{ path: 'invoice/:orderId', component: InvoiceComponent}, { path: 'invoice/:orderId', component: InvoiceComponent},
{ path: 'pmtservice', component: PmtserviceComponent}, { path: 'pmtservice', component: PmtserviceComponent},
{ path: 'test', component: XeroRegComponent},
{ path: 'login', component: LoginComponent, resolve: { response: NodeResolverService}} { 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 { MatStepperModule } from '@angular/material/stepper';
import { MatSlideToggleModule } from '@angular/material/slide-toggle'; import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { MatSnackBarModule } from '@angular/material/snack-bar'; import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatTabsModule } from '@angular/material/tabs';
import { AppRoutingModule } from './app-routing.module'; import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component'; 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 { PromptReceiptComponent } from './prompt-receipt/prompt-receipt.component';
import { NotifierComponent } from './notifier/notifier.component'; import { NotifierComponent } from './notifier/notifier.component';
import { PmtserviceComponent } from './pmtservice/pmtservice.component'; import { PmtserviceComponent } from './pmtservice/pmtservice.component';
import { XeroRegComponent } from './xeroreg/xeroreg.component';
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -73,7 +75,8 @@ import { PmtserviceComponent } from './pmtservice/pmtservice.component';
PromptInvoiceComponent, PromptInvoiceComponent,
PromptReceiptComponent, PromptReceiptComponent,
NotifierComponent, NotifierComponent,
PmtserviceComponent PmtserviceComponent,
XeroRegComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,
@ -96,6 +99,7 @@ import { PmtserviceComponent } from './pmtservice/pmtservice.component';
MatAutocompleteModule, MatAutocompleteModule,
MatSlideToggleModule, MatSlideToggleModule,
MatSnackBarModule, MatSnackBarModule,
MatTabsModule,
BrowserAnimationsModule, BrowserAnimationsModule,
FontAwesomeModule FontAwesomeModule
], ],

View file

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

View file

@ -5,6 +5,10 @@ import { UntypedFormBuilder, Validators, UntypedFormGroup, FormControl } from '@
import { User } from '../user.model'; import { User } from '../user.model';
import { Owner } from '../owner.model'; import { Owner } from '../owner.model';
var crypto = require('sha.js');
var URLSafeBase64 = require('urlsafe-base64');
var Buffer = require('buffer/').Buffer;
@Component({ @Component({
selector: 'app-settings', selector: 'app-settings',
templateUrl: './settings.component.html', templateUrl: './settings.component.html',
@ -35,6 +39,8 @@ export class SettingsComponent implements OnInit {
symbol: 'aud' symbol: 'aud'
} }
]; ];
xeroLink: string = '';
localToken: string = '';
constructor( constructor(
private fb: UntypedFormBuilder, private fb: UntypedFormBuilder,
@ -56,6 +62,16 @@ export class SettingsComponent implements OnInit {
} }
ngOnInit() { 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() { 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);
});
});
}
}