starting oauth workflow

This commit is contained in:
Nicolas Constant 2018-09-07 23:17:19 -04:00
parent deaffcc9da
commit aa248c69b3
No known key found for this signature in database
GPG Key ID: 1E9F677FB01A5688
7 changed files with 139 additions and 96 deletions

View File

@ -19,7 +19,7 @@ const url = require('url')
}))
// Open the DevTools.
//win.webContents.openDevTools()
win.webContents.openDevTools()
//open external links to browser
win.webContents.on('new-window', function(event, url){

View File

@ -1,6 +1,7 @@
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { HttpModule } from "@angular/http";
import { HttpClientModule } from '@angular/common/http';
import { NgModule, APP_INITIALIZER } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
@ -21,6 +22,7 @@ import { AccountsService } from "./services/accounts.service";
import { StreamsService } from "./services/streams.service";
import { StreamingService } from "./services/streaming.service";
import { RegisteredAppsState } from "./states/registered-apps.state";
import { AppService } from "./services/app.service";
const routes: Routes = [
{ path: "", redirectTo: "home", pathMatch: "full" },
@ -42,6 +44,7 @@ const routes: Routes = [
imports: [
BrowserModule,
HttpModule,
HttpClientModule,
FormsModule,
NgxElectronModule,
RouterModule.forRoot(routes),
@ -51,7 +54,7 @@ const routes: Routes = [
]),
NgxsStoragePluginModule.forRoot()
],
providers: [AuthService, AccountsService, StreamsService, StreamingService, { provide: APP_INITIALIZER, useFactory: settingsServiceFactory, deps: [AccountsService], multi: true }],
providers: [AppService, AuthService, AccountsService, StreamsService, StreamingService, { provide: APP_INITIALIZER, useFactory: settingsServiceFactory, deps: [AccountsService], multi: true }],
bootstrap: [AppComponent]
})
export class AppModule { }

View File

@ -2,10 +2,12 @@ import { Component, OnInit, Input } from "@angular/core";
import { Store, Select } from '@ngxs/store';
import { AuthService } from "../../services/auth.service";
import { TokenData } from "../../services/models/mastodon.interfaces";
import { TokenData, AppData } from "../../services/models/mastodon.interfaces";
import { AccountsService } from "../../services/accounts.service";
import { AddRegisteredApp, RegisteredAppsState, RegisteredAppsStateModel } from "../../states/registered-apps.state";
import { Observable } from "rxjs";
import { AppService } from "../../services/app.service";
import { ActivatedRoute } from "@angular/router";
@Component({
selector: "app-register-new-account",
@ -14,75 +16,84 @@ import { Observable } from "rxjs";
})
export class RegisterNewAccountComponent implements OnInit {
@Input() mastodonFullHandle: string;
// @Input() email: string;
// @Input() password: string;
result: string;
//@Select() registeredApps$: Observable<RegisteredAppsStateModel>;
registeredApps$: Observable<RegisteredAppsStateModel>;
constructor(
private readonly appService: AppService,
private readonly authService: AuthService,
private readonly accountsService: AccountsService,
private readonly store: Store) {
private readonly store: Store,
private readonly activatedRoute: ActivatedRoute) {
this.registeredApps$ = this.store.select(state => state.registeredapps.registeredApps);
this.registeredApps$ = this.store.select(state => state.registeredapps.registeredApps);
}
this.activatedRoute.queryParams.subscribe(params => {
const code = params['code'];
if (!code) return;
console.warn(`got a code! ${code}`);
const appDataWrapper = <AppDataWrapper>JSON.parse(localStorage.getItem('tempAuth'));
console.error('got appDataWrapper from local storage');
console.error(appDataWrapper);
this.authService.getToken(appDataWrapper.instance, appDataWrapper.appData.client_id, appDataWrapper.appData.client_secret, code, appDataWrapper.appData.redirect_uri)
.then(tokenData => {
console.warn('Got token data!');
console.warn(tokenData);
localStorage.removeItem('tempAuth');
//TODO review all this
this.accountsService.addNewAccount(appDataWrapper.instance, appDataWrapper.username, tokenData);
});
ngOnInit() {
this.registeredApps$.subscribe(x => {
console.error('registeredApps$')
console.warn(x);
});
}
ngOnInit() {
this.registeredApps$.subscribe(x => {
console.error('registeredApps$')
console.warn(x);
});
}
onSubmit(): boolean {
let fullHandle = this.mastodonFullHandle.split('@').filter(x => x != null && x !== '');
this.store
.dispatch(new AddRegisteredApp({ name: 'test', id: 15, client_id: 'dsqdqs', client_secret: 'dsqdqs', redirect_uri: 'dsqdqs' }))
.subscribe(res => {
console.error('dispatch');
console.warn(res);
const username = fullHandle[0];
const instance = fullHandle[1];
console.log(`username ${username} instance ${instance}`);
let localUrl = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '');
if (localUrl === 'file://') {
localUrl = 'http://localhost:4200';
}
const redirect_uri = localUrl + '/register';
this.appService.createNewApplication(instance, redirect_uri)
.then((appData: AppData) => {
const appDataTemp = new AppDataWrapper(username, instance, appData);
localStorage.setItem('tempAuth', JSON.stringify(appDataTemp));
let instanceUrl = `https://${instance}/oauth/authorize?scope=${encodeURIComponent('read write follow')}&response_type=code&redirect_uri=${encodeURIComponent(redirect_uri)}&client_id=${appData.client_id}`;
window.location.href = instanceUrl;
});
// let fullHandle = this.mastodonFullHandle.split('@').filter(x => x != null && x !== '');
// console.log(fullHandle[0]);
// console.log(fullHandle[1]);
// this.result = fullHandle[0] + '*' + fullHandle[1];
// window.location.href = "https://google.com";
//register app
//ask for getting token
// this.authService.getToken(this.mastodonNode, this.email, this.password)
// .then((res: TokenData) => {
// this.result = res.access_token;
// this.accountsService.addNewAccount(this.mastodonNode, this.email, res);
// })
// .catch(err => {
// this.result = err;
// });
return false;
}
}
class AppDataWrapper {
constructor(public username: string, public instance: string, public appData: AppData) {
}
}

View File

@ -65,7 +65,7 @@ export class AccountsService {
const header = new Headers();
header.append("Authorization", `Bearer ${localAccount.tokenData.access_token}`);
return this.httpService.get(localAccount.mastodonInstance + this.apiRoutes.getCurrentAccount, { headers: header }).toPromise()
return this.httpService.get('https://' + localAccount.mastodonInstance + this.apiRoutes.getCurrentAccount, { headers: header }).toPromise()
.then((res: Response) => {
const mastodonAccount = res.json() as Account;
localAccount.mastodonAccount = mastodonAccount;

View File

@ -3,23 +3,36 @@ import { Http, Response, RequestOptions } from '@angular/http';
import { map } from "rxjs/operators";
import { ApiRoutes } from './models/api.settings';
import { TokenData } from './models/mastodon.interfaces';
import { AppData } from './models/mastodon.interfaces';
import { Router } from '@angular/router';
@Injectable()
export class AppService {
private apiRoutes = new ApiRoutes();
constructor(private readonly httpService: Http) {
constructor(
private readonly httpService: Http,
private readonly router: Router) {
}
createNewApplication(mastodonUrl: string): Promise<any> {
const url = mastodonUrl + this.apiRoutes.createApp;
createNewApplication(instance: string, redirectUrl: string): Promise<AppData> {
const url = 'https://' + instance + this.apiRoutes.createApp;
// const redirect_uri = this.router.url;
// var redirect_uri = location.protocol+'//'+location.hostname+(location.port ? ':'+location.port: '');
// if(redirect_uri === 'file://'){
// redirect_uri = 'http://localhost';
// }
// console.warn(`redirect_uri ${redirect_uri}`);
// return null;
const options = new RequestOptions();
const formData = new FormData();
formData.append('client_name', 'Sengi');
formData.append('redirect_uris', '');
formData.append('redirect_uris', redirectUrl);
formData.append('scopes', 'read write follow');
formData.append('website', 'https://github.com/NicolasConstant/sengi');
@ -27,13 +40,14 @@ export class AppService {
.pipe(
map((res: Response) => {
const result = res.json();
return result as TokenData;
console.warn(result);
return result as AppData;
}))
.toPromise()
.toPromise();
// .then((res: Response) => {
// const result = res.json();
// return result as TokenData;
// });
// // .then((res: Response) => {
// // const result = res.json();
// // return result as TokenData;
// // });
}
}

View File

@ -2,47 +2,53 @@ import { Injectable } from "@angular/core";
import { Http, Response, RequestOptions } from "@angular/http";
import { ApiRoutes } from "./models/api.settings";
import { TokenData } from "./models/mastodon.interfaces";
import { HttpClient } from "@angular/common/http";
@Injectable()
export class AuthService {
private apiRoutes = new ApiRoutes();
constructor(
private readonly httpService: Http) {
private readonly httpClient: HttpClient) {
}
getToken(
mastodonNode: string, email: string, password: string): Promise<TokenData> {
// getToken(instance: string, email: string, password: string): Promise<TokenData> {
//TODO retrieve those via API
const clientId = localStorage.getItem("client_id");
const clientSecret = localStorage.getItem("client_secret");
// //TODO retrieve those via API
// const clientId = localStorage.getItem("client_id");
// const clientSecret = localStorage.getItem("client_secret");
//Retrieve Token
const url = this.getHostUrl(mastodonNode) + this.apiRoutes.getToken;
// //Retrieve Token
// const url = this.getHostUrl(instance) + this.apiRoutes.getToken;
const options = new RequestOptions();
const formData = new FormData();
// const options = new RequestOptions();
// const formData = new FormData();
formData.append("client_id", clientId);
formData.append("client_secret", clientSecret);
formData.append("grant_type", "password");
formData.append("username", email);
formData.append("password", password);
formData.append("scope", "read write follow");
// formData.append("client_id", clientId);
// formData.append("client_secret", clientSecret);
// formData.append("grant_type", "password");
// formData.append("username", email);
// formData.append("password", password);
// formData.append("scope", "read write follow");
return this.httpService.post(url, formData, options).toPromise()
.then((res: Response) => {
const result = res.json();
return result as TokenData;
});
}
// return this.httpService.post(url, formData, options).toPromise()
// .then((res: Response) => {
// const result = res.json();
// return result as TokenData;
// });
// }
private getHostUrl(url: string): string {
url = url.replace("http://", "");
if (!url.startsWith("https://")) {
url = "https://" + url;
}
return url;
// private getHostUrl(url: string): string {
// url = url.replace("http://", "");
// if (!url.startsWith("https://")) {
// url = "https://" + url;
// }
// return url;
// }
getToken(instance: string, client_id: string, client_secret: string, code: string, redirect_uri: string): Promise<TokenData> {
const url = `https://${instance}/oauth/token?client_id=${client_id}&client_secret=${client_secret}&grant_type=authorization_code&code=${code}&redirect_uri=${encodeURIComponent(redirect_uri)}`;
return this.httpClient.post<TokenData>(url, null).toPromise();
}
}

View File

@ -1,3 +1,12 @@
export interface AppData {
client_id: string;
client_secret: string;
id: string;
name: string;
redirect_uri: string;
website: string;
}
export interface TokenData {
access_token: string;
token_type: string;