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.
|
// Open the DevTools.
|
||||||
//win.webContents.openDevTools()
|
win.webContents.openDevTools()
|
||||||
|
|
||||||
//open external links to browser
|
//open external links to browser
|
||||||
win.webContents.on('new-window', function(event, url){
|
win.webContents.on('new-window', function(event, url){
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { BrowserModule } from "@angular/platform-browser";
|
import { BrowserModule } from "@angular/platform-browser";
|
||||||
import { FormsModule } from "@angular/forms";
|
import { FormsModule } from "@angular/forms";
|
||||||
import { HttpModule } from "@angular/http";
|
import { HttpModule } from "@angular/http";
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import { NgModule, APP_INITIALIZER } from "@angular/core";
|
import { NgModule, APP_INITIALIZER } from "@angular/core";
|
||||||
import { RouterModule, Routes } from "@angular/router";
|
import { RouterModule, Routes } from "@angular/router";
|
||||||
|
|
||||||
@ -21,6 +22,7 @@ import { AccountsService } from "./services/accounts.service";
|
|||||||
import { StreamsService } from "./services/streams.service";
|
import { StreamsService } from "./services/streams.service";
|
||||||
import { StreamingService } from "./services/streaming.service";
|
import { StreamingService } from "./services/streaming.service";
|
||||||
import { RegisteredAppsState } from "./states/registered-apps.state";
|
import { RegisteredAppsState } from "./states/registered-apps.state";
|
||||||
|
import { AppService } from "./services/app.service";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: "", redirectTo: "home", pathMatch: "full" },
|
{ path: "", redirectTo: "home", pathMatch: "full" },
|
||||||
@ -42,6 +44,7 @@ const routes: Routes = [
|
|||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
HttpModule,
|
HttpModule,
|
||||||
|
HttpClientModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
NgxElectronModule,
|
NgxElectronModule,
|
||||||
RouterModule.forRoot(routes),
|
RouterModule.forRoot(routes),
|
||||||
@ -51,7 +54,7 @@ const routes: Routes = [
|
|||||||
]),
|
]),
|
||||||
NgxsStoragePluginModule.forRoot()
|
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]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
export class AppModule { }
|
export class AppModule { }
|
||||||
|
@ -2,10 +2,12 @@ import { Component, OnInit, Input } from "@angular/core";
|
|||||||
import { Store, Select } from '@ngxs/store';
|
import { Store, Select } from '@ngxs/store';
|
||||||
|
|
||||||
import { AuthService } from "../../services/auth.service";
|
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 { AccountsService } from "../../services/accounts.service";
|
||||||
import { AddRegisteredApp, RegisteredAppsState, RegisteredAppsStateModel } from "../../states/registered-apps.state";
|
import { AddRegisteredApp, RegisteredAppsState, RegisteredAppsStateModel } from "../../states/registered-apps.state";
|
||||||
import { Observable } from "rxjs";
|
import { Observable } from "rxjs";
|
||||||
|
import { AppService } from "../../services/app.service";
|
||||||
|
import { ActivatedRoute } from "@angular/router";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-register-new-account",
|
selector: "app-register-new-account",
|
||||||
@ -14,75 +16,84 @@ import { Observable } from "rxjs";
|
|||||||
})
|
})
|
||||||
export class RegisterNewAccountComponent implements OnInit {
|
export class RegisterNewAccountComponent implements OnInit {
|
||||||
@Input() mastodonFullHandle: string;
|
@Input() mastodonFullHandle: string;
|
||||||
// @Input() email: string;
|
|
||||||
// @Input() password: string;
|
|
||||||
result: string;
|
result: string;
|
||||||
|
|
||||||
//@Select() registeredApps$: Observable<RegisteredAppsStateModel>;
|
|
||||||
registeredApps$: Observable<RegisteredAppsStateModel>;
|
registeredApps$: Observable<RegisteredAppsStateModel>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
private readonly appService: AppService,
|
||||||
private readonly authService: AuthService,
|
private readonly authService: AuthService,
|
||||||
private readonly accountsService: AccountsService,
|
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 {
|
onSubmit(): boolean {
|
||||||
|
let fullHandle = this.mastodonFullHandle.split('@').filter(x => x != null && x !== '');
|
||||||
|
|
||||||
this.store
|
const username = fullHandle[0];
|
||||||
.dispatch(new AddRegisteredApp({ name: 'test', id: 15, client_id: 'dsqdqs', client_secret: 'dsqdqs', redirect_uri: 'dsqdqs' }))
|
const instance = fullHandle[1];
|
||||||
.subscribe(res => {
|
console.log(`username ${username} instance ${instance}`);
|
||||||
console.error('dispatch');
|
|
||||||
console.warn(res);
|
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;
|
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();
|
const header = new Headers();
|
||||||
header.append("Authorization", `Bearer ${localAccount.tokenData.access_token}`);
|
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) => {
|
.then((res: Response) => {
|
||||||
const mastodonAccount = res.json() as Account;
|
const mastodonAccount = res.json() as Account;
|
||||||
localAccount.mastodonAccount = mastodonAccount;
|
localAccount.mastodonAccount = mastodonAccount;
|
||||||
|
@ -3,23 +3,36 @@ import { Http, Response, RequestOptions } from '@angular/http';
|
|||||||
import { map } from "rxjs/operators";
|
import { map } from "rxjs/operators";
|
||||||
|
|
||||||
import { ApiRoutes } from './models/api.settings';
|
import { ApiRoutes } from './models/api.settings';
|
||||||
import { TokenData } from './models/mastodon.interfaces';
|
import { AppData } from './models/mastodon.interfaces';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AppService {
|
export class AppService {
|
||||||
private apiRoutes = new ApiRoutes();
|
private apiRoutes = new ApiRoutes();
|
||||||
|
|
||||||
constructor(private readonly httpService: Http) {
|
constructor(
|
||||||
|
private readonly httpService: Http,
|
||||||
|
private readonly router: Router) {
|
||||||
}
|
}
|
||||||
|
|
||||||
createNewApplication(mastodonUrl: string): Promise<any> {
|
createNewApplication(instance: string, redirectUrl: string): Promise<AppData> {
|
||||||
const url = mastodonUrl + this.apiRoutes.createApp;
|
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 options = new RequestOptions();
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
|
|
||||||
formData.append('client_name', 'Sengi');
|
formData.append('client_name', 'Sengi');
|
||||||
formData.append('redirect_uris', '');
|
formData.append('redirect_uris', redirectUrl);
|
||||||
formData.append('scopes', 'read write follow');
|
formData.append('scopes', 'read write follow');
|
||||||
formData.append('website', 'https://github.com/NicolasConstant/sengi');
|
formData.append('website', 'https://github.com/NicolasConstant/sengi');
|
||||||
|
|
||||||
@ -27,13 +40,14 @@ export class AppService {
|
|||||||
.pipe(
|
.pipe(
|
||||||
map((res: Response) => {
|
map((res: Response) => {
|
||||||
const result = res.json();
|
const result = res.json();
|
||||||
return result as TokenData;
|
console.warn(result);
|
||||||
|
return result as AppData;
|
||||||
}))
|
}))
|
||||||
.toPromise()
|
.toPromise();
|
||||||
|
|
||||||
// .then((res: Response) => {
|
// // .then((res: Response) => {
|
||||||
// const result = res.json();
|
// // const result = res.json();
|
||||||
// return result as TokenData;
|
// // return result as TokenData;
|
||||||
// });
|
// // });
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,47 +2,53 @@ import { Injectable } from "@angular/core";
|
|||||||
import { Http, Response, RequestOptions } from "@angular/http";
|
import { Http, Response, RequestOptions } from "@angular/http";
|
||||||
import { ApiRoutes } from "./models/api.settings";
|
import { ApiRoutes } from "./models/api.settings";
|
||||||
import { TokenData } from "./models/mastodon.interfaces";
|
import { TokenData } from "./models/mastodon.interfaces";
|
||||||
|
import { HttpClient } from "@angular/common/http";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class AuthService {
|
export class AuthService {
|
||||||
private apiRoutes = new ApiRoutes();
|
private apiRoutes = new ApiRoutes();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly httpService: Http) {
|
private readonly httpClient: HttpClient) {
|
||||||
}
|
}
|
||||||
|
|
||||||
getToken(
|
// getToken(instance: string, email: string, password: string): Promise<TokenData> {
|
||||||
mastodonNode: string, email: string, password: string): Promise<TokenData> {
|
|
||||||
|
|
||||||
//TODO retrieve those via API
|
// //TODO retrieve those via API
|
||||||
const clientId = localStorage.getItem("client_id");
|
// const clientId = localStorage.getItem("client_id");
|
||||||
const clientSecret = localStorage.getItem("client_secret");
|
// const clientSecret = localStorage.getItem("client_secret");
|
||||||
|
|
||||||
//Retrieve Token
|
// //Retrieve Token
|
||||||
const url = this.getHostUrl(mastodonNode) + this.apiRoutes.getToken;
|
// const url = this.getHostUrl(instance) + this.apiRoutes.getToken;
|
||||||
|
|
||||||
const options = new RequestOptions();
|
// const options = new RequestOptions();
|
||||||
const formData = new FormData();
|
// const formData = new FormData();
|
||||||
|
|
||||||
formData.append("client_id", clientId);
|
// formData.append("client_id", clientId);
|
||||||
formData.append("client_secret", clientSecret);
|
// formData.append("client_secret", clientSecret);
|
||||||
formData.append("grant_type", "password");
|
// formData.append("grant_type", "password");
|
||||||
formData.append("username", email);
|
// formData.append("username", email);
|
||||||
formData.append("password", password);
|
// formData.append("password", password);
|
||||||
formData.append("scope", "read write follow");
|
// formData.append("scope", "read write follow");
|
||||||
|
|
||||||
return this.httpService.post(url, formData, options).toPromise()
|
// return this.httpService.post(url, formData, options).toPromise()
|
||||||
.then((res: Response) => {
|
// .then((res: Response) => {
|
||||||
const result = res.json();
|
// const result = res.json();
|
||||||
return result as TokenData;
|
// return result as TokenData;
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
private getHostUrl(url: string): string {
|
// private getHostUrl(url: string): string {
|
||||||
url = url.replace("http://", "");
|
// url = url.replace("http://", "");
|
||||||
if (!url.startsWith("https://")) {
|
// if (!url.startsWith("https://")) {
|
||||||
url = "https://" + url;
|
// url = "https://" + url;
|
||||||
}
|
// }
|
||||||
return 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 {
|
export interface TokenData {
|
||||||
access_token: string;
|
access_token: string;
|
||||||
token_type: string;
|
token_type: string;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user