starting oauth workflow
This commit is contained in:
parent
deaffcc9da
commit
aa248c69b3
2
main.js
2
main.js
|
@ -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){
|
||||
|
|
|
@ -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 { }
|
||||
|
|
|
@ -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,21 +16,43 @@ 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 => {
|
||||
|
@ -36,53 +60,40 @@ export class RegisterNewAccountComponent implements OnInit {
|
|||
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) {
|
||||
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
// // });
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue