Hijack links inside email that go to billing site and add SSO to them

This commit is contained in:
Juan Tejada 2016-05-26 15:16:48 -07:00
parent 2ba9aedfe9
commit 4c4f463f4b
5 changed files with 50 additions and 36 deletions

View file

@ -1,8 +1,6 @@
import React from 'react';
import {shell} from 'electron';
import {Actions, IdentityStore} from 'nylas-exports';
import {Actions, NylasAPI, IdentityStore} from 'nylas-exports';
import {RetinaImg} from 'nylas-component-kit';
import request from 'request';
class OpenIdentityPageButton extends React.Component {
static propTypes = {
@ -19,35 +17,13 @@ class OpenIdentityPageButton extends React.Component {
}
_onClick = () => {
const identity = IdentityStore.identity();
if (!identity) {
return;
}
if (!this.props.destination.startsWith('/')) {
throw new Error("destination must start with a leading slash.");
}
this.setState({loading: true});
request({
method: 'POST',
url: `${IdentityStore.URLRoot}/n1/login-link`,
json: true,
body: {
destination: this.props.destination,
account_token: identity.token,
},
}, (error, response = {}, body) => {
this.setState({loading: false});
if (error || !body.startsWith('http')) {
// Single-sign on attempt failed. Rather than churn the user right here,
// at least try to open the page directly in the browser.
shell.openExternal(`${IdentityStore.URLRoot}${this.props.destination}`);
} else {
shell.openExternal(body);
}
});
const identity = IdentityStore.identity();
if (!identity) { return }
NylasAPI.navigateToBillingSite()
.then(() => {
this.setState({loading: false})
})
}
render() {

View file

@ -51,8 +51,8 @@
.btn {
width: 150px;
text-align: center;
&+.btn {
margin-left: @padding-base-horizontal;
&:first-child {
margin-right: @padding-base-horizontal;
}
}
}

View file

@ -1,7 +1,9 @@
React = require 'react'
ReactDOM = require 'react-dom'
{Utils,
NylasAPI,
RegExpUtils,
IdentityStore,
SearchableComponentMaker,
SearchableComponentStore}= require 'nylas-exports'
IFrameSearcher = require('../searchable-components/iframe-searcher').default
@ -158,6 +160,12 @@ class EventedIFrame extends React.Component
e.preventDefault()
# If this is a link to our billing site, attempt single sign on instead of
# just following the link directly
if rawHref.startsWith(IdentityStore.URLRoot)
NylasAPI.navigateToBillingSite(IdentityStore.identity(), '/billing')
return
# It's important to send the raw `href` here instead of the target.
# The `target` comes from the document context of the iframe, which
# as of Electron 0.36.9, has different constructor function objects

View file

@ -1,10 +1,11 @@
_ = require 'underscore'
{remote} = require 'electron'
{remote, shell} = require 'electron'
request = require 'request'
NylasLongConnection = require('./nylas-long-connection').default
Utils = require './models/utils'
Account = require('./models/account').default
Message = require('./models/message').default
IdentityStore = require('./stores/identity-store').default
Actions = require './actions'
{APIError} = require './errors'
PriorityUICoordinator = require '../priority-ui-coordinator'
@ -428,4 +429,30 @@ You can review and revoke Offline Access for plugins at any time from Preference
path: "/auth/plugin?client_id=#{pluginId}"
})
navigateToBillingSite: (identity, destination) =>
unless identity
throw new Error("must provide an identity object")
if (not destination) or (not destination.startsWith('/'))
throw new Error("destination must start with a leading slash.")
return new Promise (resolve) =>
request({
method: 'POST',
url: "#{IdentityStore.URLRoot}/n1/login-link",
json: true,
body: {
destination: destination,
account_token: identity.token,
},
}, (error, response = {}, body) =>
if error or !body.startsWith('http')
# Single-sign on attempt failed. Rather than churn the user right here,
# at least try to open the page directly in the browser.
shell.openExternal("#{IdentityStore.URLRoot}#{destination}")
else
shell.openExternal(body)
resolve()
)
module.exports = new NylasAPI()

View file

@ -6,14 +6,13 @@ import {ipcRenderer} from 'electron';
const configIdentityKey = "nylas.identity";
const keytarServiceName = 'Nylas';
const keytarIdentityKey = 'Nylas Account';
const URLRoot = "https://billing-staging.nylas.com";
class IdentityStore extends NylasStore {
constructor() {
super();
this.URLRoot = "https://billing-staging.nylas.com";
// TODO
this._trialDaysRemaining = 14
@ -34,6 +33,10 @@ class IdentityStore extends NylasStore {
}
}
get URLRoot() {
return URLRoot;
}
identity() {
return this._identity;
}