Skip to content

Commit

Permalink
Merge pull request #1440 from SailingSteve/steveWebAppApril6
Browse files Browse the repository at this point in the history
WebApp changes for Cordova Android -- oAuth through Twitter now works
  • Loading branch information
DaleMcGrew authored Apr 6, 2018
2 parents 0a0cfd1 + 66ce945 commit efe28d9
Show file tree
Hide file tree
Showing 12 changed files with 178 additions and 104 deletions.
92 changes: 46 additions & 46 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"react-dom": "^15.6.2",
"react-helmet": "^3.3.0",
"react-iframe-resizer-super": "^0.2.0",
"react-player": "^0.14.1",
"react-player": "^1.3.1",
"react-router-scroll": "^0.4.4",
"react-slick": "^0.14.5",
"react-slide-out": "^0.1.4",
Expand Down
18 changes: 11 additions & 7 deletions src/js/Application.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import PropTypes from "prop-types";
import { ToastContainer } from "react-toastify";
import BookmarkActions from "./actions/BookmarkActions";
import cookies from "./utils/cookies";
import { historyPush, isCordova, cordovaOpenSafariView, isWebApp } from "./utils/cordovaUtils";
import { historyPush, cordovaOpenSafariView, isAndroid, isCordova, isIOS,
isWebApp } from "./utils/cordovaUtils";
import ElectionActions from "./actions/ElectionActions";
import FooterBarCordova from "./components/Navigation/FooterBarCordova";
import FriendActions from "./actions/FriendActions";
Expand Down Expand Up @@ -59,9 +60,10 @@ export default class Application extends Component {

initCordova () {
console.log("Application initCordova ------------ " + __filename);
console.log("------------------ device.platform = " + device.platform);
if (isCordova()) {
window.handleOpenURL = function (url) {
console.log("Application handleOpenUrl: " + url);
console.log("---------------xxxxxx-------- Application handleOpenUrl: " + url);
if (url.startsWith("wevotetwitterscheme://")) {
console.log("window.handleOpenURL received wevotetwitterscheme: " + url);
let search = url.replace(new RegExp("&", "g"), "&");
Expand Down Expand Up @@ -388,8 +390,10 @@ export default class Application extends Component {
"headroom-getting-started__margin" : isWebApp() ? "headroom-wrapper" : "headroom-wrapper__cordova";

let pageHeaderStyle = this.state.we_vote_branding_off ? "page-header__container_branding_off headroom" : "page-header__container headroom";
if (isCordova()) {
pageHeaderStyle += " page-header-cordova";
if (isIOS()) {
pageHeaderStyle = "page-header__container headroom page-header-cordova-ios"; // Note March 2018: no headroom.js for Cordova
} else if (isAndroid()) {
pageHeaderStyle = "page-header__container headroom";
}

let footerStyle = this.state.showFooter ? "footroom-wrapper" : "footroom-wrapper__hide";
Expand All @@ -412,7 +416,7 @@ export default class Application extends Component {

return <div className="app-base" id="app-base-id">
<ToastContainer closeButton={false} />
{ isCordova() && <div className={"ios7plus-spacer"} /> }
{ isCordova() && isIOS() && <div className={"ios7plus-spacer"} /> }
<div className={headRoomSize}>
<div ref="pageHeader" className={pageHeaderStyle}>
{ showBackToHeader ?
Expand Down Expand Up @@ -440,7 +444,7 @@ export default class Application extends Component {
} else if (settingsMode) {
return <div className="app-base" id="app-base-id">
<ToastContainer closeButton={false} />
{ isCordova() && <div className={"ios7plus-spacer"} /> }
{ isCordova() && isIOS() && <div className={"ios7plus-spacer"} /> }
<div className={headRoomSize}>
<div ref="pageHeader" className={pageHeaderStyle}>
{/* March 2018: One of HeaderBackToBar OR HeaderBar is displayed, AND under some circumstances HeaderGettingStartedBar is
Expand All @@ -467,7 +471,7 @@ export default class Application extends Component {
// This handles other pages, like Welcome and the Ballot display
return <div className="app-base" id="app-base-id">
<ToastContainer closeButton={false} />
{ isCordova() && <div className={"ios7plus-spacer"} /> }
{ isCordova() && isIOS() && <div className={"ios7plus-spacer"} /> }
<div className={headRoomSize}>
<div ref="pageHeader" className={pageHeaderStyle}>
{/* March 2018: One of HeaderBackToBar OR HeaderBar is displayed, AND under some circumstances HeaderGettingStartedBar is
Expand Down
78 changes: 74 additions & 4 deletions src/js/components/Twitter/TwitterSignIn.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
import { Button } from "react-bootstrap";
import { renderLog } from "../../utils/logging";
import { oAuthLog, renderLog } from "../../utils/logging";
import { $ajax } from "../../utils/service";
import cookies from "../../utils/cookies";
import { isWebApp, cordovaOpenSafariView } from "../../utils/cordovaUtils";
import { isWebApp, cordovaOpenSafariView, isIOS, isAndroid, historyPush } from "../../utils/cordovaUtils";
import webAppConfig from "../../config";
import TwitterActions from "../../actions/TwitterActions";

const returnURL = webAppConfig.WE_VOTE_URL_PROTOCOL + webAppConfig.WE_VOTE_HOSTNAME + "/twitter_sign_in";

Expand Down Expand Up @@ -57,8 +58,77 @@ export default class TwitterSignIn extends Component {
twitterSignInWebAppCordova () {
const requestURL = webAppConfig.WE_VOTE_SERVER_API_ROOT_URL + "twitterSignInStart" +
"?cordova=true&voter_device_id=" + cookies.getItem("voter_device_id") + "&return_url=http://nonsense.com";
console.log("twitterSignInWebAppCordova requestURL: " + requestURL);
cordovaOpenSafariView(requestURL, 50);
oAuthLog("twitterSignInWebAppCordova requestURL: " + requestURL);
if (isIOS()) {
cordovaOpenSafariView(requestURL, 50);
} else if (isAndroid()) {
// April 6, 2018: Needs Steve's PR to handle customscheme
// https://github.com/apache/cordova-plugin-inappbrowser/pull/263
let inAppBrowserRef = cordova.InAppBrowser.open(requestURL, "_blank", "toolbar=no,location=yes,hardwareback=no");
inAppBrowserRef.addEventListener("exit", function () {
oAuthLog("inAppBrowserRef on exit: ", requestURL);
});

inAppBrowserRef.addEventListener("customscheme", function (event) {
oAuthLog("customscheme: ", event.url);
TwitterSignIn.handleTwitterOpenURL(event.url);

//inAppBrowserRef.close();
});
}
}

static handleTwitterOpenURL (url) {
oAuthLog("---------------xxxxxx-------- Application handleTwitterOpenUrl: " + url);
if (url.startsWith("wevotetwitterscheme://")) {
oAuthLog("handleTwitterOpenURL received wevotetwitterscheme: " + url);
let search = url.replace(new RegExp("&amp;", "g"), "&");
let urlParams = new URLSearchParams(search);
if (urlParams.has("twitter_redirect_url")) {
let redirectURL = urlParams.get("twitter_redirect_url");
oAuthLog("twitterSignIn cordova, redirecting to: " + redirectURL);

if (isIOS()) {
// eslint-disable-next-line no-undef
SafariViewController.hide(); // Hide the previous WKWebView
cordovaOpenSafariView(redirectURL, 500);
} else {
oAuthLog("redirectURL: ", redirectURL);
let inAppBrowserRef = cordova.InAppBrowser.open(redirectURL, "_blank", "toolbar=no,location=yes,hardwareback=no");
inAppBrowserRef.addEventListener('exit', function () {
oAuthLog("inAppBrowserRef on exit: ", redirectURL);
});

inAppBrowserRef.addEventListener('customscheme', function (event) {
oAuthLog("customscheme: ", event.url);
TwitterSignIn.handleTwitterOpenURL(event.url);
inAppBrowserRef.close();
});
}
} else if (urlParams.has("access_token_and_secret_returned")) {
if (urlParams.get("success") === "True") {
oAuthLog("twitterSignIn cordova, received secret -- push /ballot");
TwitterActions.twitterSignInRetrieve();
historyPush("/ballot");
} else {
oAuthLog("twitterSignIn cordova, FAILED to receive secret -- push /twitter_sign_in");
historyPush("/twitter_sign_in");
}
} else if (urlParams.has("twitter_handle_found") && urlParams.get("twitter_handle_found") === "True") {
oAuthLog("twitterSignIn cordova, twitter_handle_found -- push /twitter_sign_in -- received handle = " + urlParams.get("twitter_handle"));

if (isIOS()) {
// eslint-disable-next-line no-undef
SafariViewController.hide(); // Hide the previous WKWebView
}

historyPush("/twitter_sign_in");
} else {
console.log("ERROR in window.handleOpenURL, NO MATCH");
}
} else {
console.log("ERROR: window.handleOpenURL received invalid url: " + url);
}
}

render () {
Expand Down
4 changes: 3 additions & 1 deletion src/js/dispatcher/Dispatcher.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { httpLog } from "../utils/logging";

var Dispatcher = require("flux/lib/Dispatcher");

Dispatcher.prototype.$ajax = require("../utils/service").$ajax;
Expand All @@ -10,7 +12,7 @@ Dispatcher.prototype.loadEndpoint = function (endpoint, data = {}) {
endpoint,
data: data,
success: (res) => {
// console.log("Ajax response to endpoint: " + endpoint);
httpLog("AJAX Response to endpoint: " + endpoint);
this.dispatch({ type: endpoint, res });
},

Expand Down
9 changes: 7 additions & 2 deletions src/js/routes/VoterGuide/OrganizationVoterGuide.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import PropTypes from "prop-types";
import { Link } from "react-router";
import { Button } from "react-bootstrap";
import AnalyticsActions from "../../actions/AnalyticsActions";
import { historyPush, isWebApp } from "../../utils/cordovaUtils";
import { historyPush, isIOS, isWebApp } from "../../utils/cordovaUtils";
import FollowToggle from "../../components/Widgets/FollowToggle";
import VoterGuideStore from "../../stores/VoterGuideStore";
import HeaderBar from "../../components/Navigation/HeaderBar";
Expand Down Expand Up @@ -153,7 +153,12 @@ export default class OrganizationVoterGuide extends Component {
let isVoterOwner = this.state.organization.organization_we_vote_id !== undefined &&
this.state.organization.organization_we_vote_id === this.state.voter.linked_organization_we_vote_id;

let pageHeaderStyle = isWebApp() ? "page-header__container headroom" : "page-header__container headroom page-header-cordova";
let pageHeaderStyle = "page-header__container headroom";
if (isIOS()) {
pageHeaderStyle = "page-header__container page-header-cordova-ios"; // Note March 2018: no headroom.js for Cordova
} else if (isAndroid()) {
pageHeaderStyle = "page-header__container";
}

if (!organizationId) {
let floatRight = {
Expand Down
9 changes: 9 additions & 0 deletions src/js/utils/cordovaUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,12 @@ export function deviceTypeString () {

return deviceString;
}

export function isIOS () {
return isCordova() && window.device && device.platform === "iOS";
}

export function isAndroid () {
return isCordova() && window.device && device.platform === "Android";
}

13 changes: 12 additions & 1 deletion src/js/utils/logging.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function renderLog (filePath, suffix) {

// Log http requests and cookie CHANGES
export function httpLog (text, res) {
if (webAppConfig.LOG_NATIVE_HTTP_REQUESTS) {
if (webAppConfig.LOG_HTTP_REQUESTS) {
if (res) {
console.log(text, res);
} else {
Expand All @@ -39,3 +39,14 @@ export function httpLog (text, res) {
}
}

// Log oAuth steps
export function oAuthLog (text, res) {
if (webAppConfig.LOG_SIGNIN_STEPS) {
if (res) {
console.log(">> oAuth >> ", text, res);
} else {
console.log(">> oAuth >> ", text);
}
}
}

36 changes: 2 additions & 34 deletions src/js/utils/service.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import assign from "object-assign";
import url from "url";
import cookies from "./cookies";
import webAppConfig from "../config";
import { httpLog } from "../utils/logging";

// import { isCordova } from "../utils/cordovaUtils";

Expand Down Expand Up @@ -40,40 +41,7 @@ export function $ajax (options) {
options.error = options.error || defaults.error;
options.url = url.resolve(defaults.baseUrl, options.endpoint) + "/";

// if (isCordova()) {
// console.log("AJAX URL: " + options.url);
// }
httpLog("AJAX URL: " + options.url);

return $.ajax(options);
}

// Commented out March 2018, feel free to delete in a few months. This seems to be abandoned.
//const DEBUG = false;
// export function get (options) {
// var opts = assign(defaults, options);
//
// opts.url = url.resolve(opts.baseUrl, opts.endpoint);
// // We add voter_device_id to all endpoint calls
// opts.query.voter_device_id = cookies.getItem("voter_device_id");
//
// return new Promise( (resolve, reject) => new request.Request("GET", opts.url)
// .accept(opts.dataType)
// .query(opts.query)
// .withCredentials()
// .end((err, res) => {
// if (err) {
// if (opts.error instanceof Function === true)
// opts.error(err || res.body);
//
// reject(err);
// } else {
// if (opts.success instanceof Function === true)
// opts.success(res.body);
// else if (DEBUG)
// console.warn(res.body);
//
// resolve(res.body);
// }
// })
// );
// }
2 changes: 1 addition & 1 deletion src/sass/components/_header.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ $space-search-right: 10%;
}
}

.page-header-cordova {
.page-header-cordova-ios {
margin: $space-header-height auto $space-none;
}

Expand Down
5 changes: 2 additions & 3 deletions src/sass/components/_navigator.scss
Original file line number Diff line number Diff line change
Expand Up @@ -383,8 +383,7 @@ $container-margin: -15px;
}

&__text {
font-weight: 200 !important;
font-size: 13pt !important;
color: $blue !important;
font-weight: 300;
font-size: 13pt;
}
}
14 changes: 10 additions & 4 deletions www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,20 @@
* Enable inline JS: add 'unsafe-inline' to default-src
Steve 1/18/18: I was working on making all the correct policies, and decided to just make it wide open for now.
Wide open security policy for Apache Cordova. TODO: We should close this down
default-src 'self' data: http: https: localhost: wevotetwitterscheme: gap://* https://ssl.gstatic.com ;
-->
<meta http-equiv="Content-Security-Policy" content="
default-src * gap: ;
default-src * data: content: gap: https://ssl.gstatic.com;
img-src *;
style-src * 'unsafe-inline';
script-src * 'unsafe-inline';
frame-src http://*.facebook.com https://*.facebook.com https://*.twitter.com gap: ;
child-src gap://* ;
font-src *;
media-src *;
img-src * data:;
" />
<!--img-src https: data: file: android-webview-video-poster: https://api.wevoteusa.org;-->
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport"
Expand Down Expand Up @@ -67,9 +73,9 @@
font-size: 32px;
font-weight: normal;
color: #fff;
">Loading We Vote...
">Loading We Vote CORDOVA2...
</h1>
<div class="u-loading-spinner u-loading-spinner--light">Loading We Vote...</div>
<div class="u-loading-spinner u-loading-spinner--light">Loading We Vote CORDOVA...</div>
</div>
</div>
<!--<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>-->
Expand Down

0 comments on commit efe28d9

Please sign in to comment.