-
Notifications
You must be signed in to change notification settings - Fork 6
/
oAuthController.jsx
111 lines (102 loc) · 4.11 KB
/
oAuthController.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import React, { Component } from "react";
import CreateAuthToken from "../Authentication/createAuthToken";
import Helper from "../Utility/helper";
import ImageComponent from "../Components/GroupSubComponents/imageComponent";
/**
* Class component that displays login page, which contains a button that when clicked, routes user to Sonos login page
* Upon successful login, access token is generated and passed into the handler function passed through props
* User stays on login page until login is successful
*/
export default class OAuthController extends Component {
/**
* @param props.accessTokenHandler Handler function that updates access token status in RouteComponents
*/
constructor(props) {
super(props);
// When code is generated, this is set to true and auth token is created
this.codeGeneratedFlag = false;
// Needed to get access token from Sonos API
this.code = null;
// Helper class contains various helper methods for use throughout the application
this.helper = new Helper();
}
/**
* Gets param code and sets this.code and this.codeGeneratedFlag
* Called before CreateAuthToken, as CreateAuthToken depends on the param code
*/
getCode = () => {
// Gets param code from current URL for later use in getting access token from Sonos API
// Param code is generated when Sonos login is completed
let cur_url = window.location.href;
const params = new URLSearchParams(cur_url);
const code_generated = params.get("code");
// If param code was successfully retrieved, sets code value and sets codeGeneratedFlag to true, causing CreateAuthToken to be called
// Otherwise, signals to routingController that it should retry authentication
if (code_generated !== null) {
this.codeGeneratedFlag = true;
this.code = code_generated;
} else {
this.props.accessTokenHandler("DOES NOT EXIST");
}
};
/**
* Passed through props to CreateAuthToken
* Sets value of access token status in RouteComponents by calling accessTokenHandler function passed through props
* @param flag {boolean} True if user has logged in, false otherwise
* @param response {JSON} Sonos API response from CreateAuthToken
*/
isLoggedInHandler = (flag, response) => {
// Data retrieved from CreateAuthToken that is to be stored in the current window
const accessTokenData = {
token: response["access_token"],
refresh_token: response["refresh_token"],
token_type: response["token_type"],
expiry: response["expires_in"],
tokenTimestamp: Math.floor(Date.now() / 1000),
};
// Can be accessed from other pages within the sample app
window.localStorage.setItem(
"accessToken",
JSON.stringify(accessTokenData)
);
// Updates access token value in RouteComponents
this.props.accessTokenHandler(flag ? "VALID" : "DOES NOT EXIST");
};
render() {
// Gets param code first since it is needed for authentication
this.getCode();
return (
// Displays login page
<div className="background">
<div className="main_page">
<div className="oauth_bkg">
<img
src={require("../../images/sonos_background.png")}
width="100%"
alt="Login page background image"
/>
</div>
<div className="login_with_sonos_text">
<p>Log into your Sonos account</p>
</div>
{/* Login button that when clicked, takes user to Sonos login URL */}
<a href={this.helper.getOAuthUrl()} className="oauthhref">
<button type="button" className="login_btn">
Log In
</button>
</a>
</div>
<div className="login_to_sonos" align="center">
{/* When param code is retrieved, auth token is created and value in RouteComponents is updated */}
{this.codeGeneratedFlag && (
<CreateAuthToken
b64_encoded_string={this.helper.getB64KeySecret()}
code={this.code}
isLoggedInHandler={this.isLoggedInHandler}
/>
)}
</div>
</div>
);
}
}