diff --git a/main.js b/main.js index c3797209..0ea8eb88 100644 --- a/main.js +++ b/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){ diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 56b1ee37..772b5909 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -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 { } diff --git a/src/app/pages/register-new-account/register-new-account.component.ts b/src/app/pages/register-new-account/register-new-account.component.ts index 23d53518..5b2a0461 100644 --- a/src/app/pages/register-new-account/register-new-account.component.ts +++ b/src/app/pages/register-new-account/register-new-account.component.ts @@ -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; registeredApps$: Observable; 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 = 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) { + + } +} \ No newline at end of file diff --git a/src/app/services/accounts.service.ts b/src/app/services/accounts.service.ts index 271a7ab2..5e46a332 100644 --- a/src/app/services/accounts.service.ts +++ b/src/app/services/accounts.service.ts @@ -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; diff --git a/src/app/services/app.service.ts b/src/app/services/app.service.ts index 3eb0b009..ff09da31 100644 --- a/src/app/services/app.service.ts +++ b/src/app/services/app.service.ts @@ -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 { - const url = mastodonUrl + this.apiRoutes.createApp; + createNewApplication(instance: string, redirectUrl: string): Promise { + 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; + // // }); } } \ No newline at end of file diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index 5529b965..3ed58822 100644 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -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 { + // getToken(instance: string, email: string, password: string): Promise { - //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 { + 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(url, null).toPromise(); } } diff --git a/src/app/services/models/mastodon.interfaces.ts b/src/app/services/models/mastodon.interfaces.ts index 608829b2..773bac1f 100644 --- a/src/app/services/models/mastodon.interfaces.ts +++ b/src/app/services/models/mastodon.interfaces.ts @@ -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;