mirror of
https://github.com/Foundry376/Mailspring.git
synced 2025-11-11 17:00:44 +08:00
Hijack links inside email that go to billing site and add SSO to them
This commit is contained in:
parent
2ba9aedfe9
commit
4c4f463f4b
5 changed files with 50 additions and 36 deletions
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -51,8 +51,8 @@
|
|||
.btn {
|
||||
width: 150px;
|
||||
text-align: center;
|
||||
&+.btn {
|
||||
margin-left: @padding-base-horizontal;
|
||||
&:first-child {
|
||||
margin-right: @padding-base-horizontal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue