Skip to content

Instantly share code, notes, and snippets.

@pcoady
Last active March 18, 2020 10:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save pcoady/5633ac8d8f77e4a898f3 to your computer and use it in GitHub Desktop.
Save pcoady/5633ac8d8f77e4a898f3 to your computer and use it in GitHub Desktop.
BackSpace Academy Certified Developer Associate IAM S3 Lab
body {
background: url('supermarket.jpg') no-repeat center center fixed;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
}
.glyphicon-refresh-animate {
-animation: spin .7s infinite linear;
-webkit-animation: spin2 .7s infinite linear;
}
@-webkit-keyframes spin2 {
from { -webkit-transform: rotate(0deg);}
to { -webkit-transform: rotate(360deg);}
}
@keyframes spin {
from { transform: scale(1) rotate(0deg);}
to { transform: scale(1) rotate(360deg);}
}
#pageSpinner{
display: none;
}
(function () {
var facebookAppId = '878434192277580';
var roleArn = 'arn:aws:iam::802694931986:role/facebookBackSpace';
var bucketName = 'lab.backspace.academy';
AWS.config.region = 'us-east-1';
var userLoggedIn = false;
var userSync = false;
var S3 = new AWS.S3({
params: {
Bucket: bucketName
}
});
var fbUserId = '0';
var fbToken = '0';
var prefix = '0'
var objKeys = [];
var objKeysList = '';
/******************** Startup functions ***********************************/
$.jGrowl.defaults.closerTemplate = '<div class="alert alert-info">Close All</div>';
loadObjKeys();
loadModals();
/******************** Button Events ***************************************/
$('#btnCreate').on('click', function (event) {
createShoppingList();
});
$('#btnSync').on('click', function (event) {
console.log('Starting sync...');
syncShoppingList();
});
$('#btnDelete').on('click', function (event) {
deleteShoppingList($('#dropdownDeleteList')[0].selectedIndex);
});
$('#dropdownReadList').on('click', function (event) {
readShoppingList($('#dropdownReadList')[0].selectedIndex);
});
/******************* Facebook Login ***************************************/
function statusChangeCallback(response) {
console.log('Facebook response: ')
console.log(response);
if (response.status === 'connected') {
// Logged into your app and Facebook. Pass details to app.
testAPI();
setupAWS(response);
} else if (response.status === 'not_authorized') {
document.getElementById('status').innerHTML = 'Please log ' +
'into this app.';
} else {
document.getElementById('status').innerHTML = 'Please log ' +
'into Facebook.';
}
}
function checkLoginState() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
window.fbAsyncInit = function() {
FB.init({
appId : facebookAppId,
cookie : true,
xfbml : true,
version : 'v2.2'
});
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
};
(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = '//connect.facebook.net/en_US/sdk.js';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
function testAPI() {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Successful login for: ' + response.name);
document.getElementById('status').innerHTML =
'Thanks for logging in, ' + response.name + '!';
});
document.getElementById('status').innerHTML = 'Logged ' +
'into Facebook.';
}
function validLogin(){
// Checks you have logged in and token hasn't expired
var tempDate = new Date();
var tempValid = true;
if (!userLoggedIn){
tempValid = false;
growl('danger', 'Facebook Error', 'You are currently not logged in with Facebook!');
}
else if (tempDate >= fbTokenExpires){
tempValid = false;
growl('danger', 'Facebook Error', 'Facebook token expired. Please log in again');
}
return tempValid;
}
/******************* Create temporary AWS credentials *********************/
Date.prototype.addHours= function(h){
this.setHours(this.getHours()+h);
return this;
};
function setupAWS(response){
fbToken = response.authResponse.accessToken;
console.log('Facebook token: ' + JSON.stringify(fbToken))
fbTokenExpires = new Date().addHours(response.authResponse.expires/3600);
fbUserId = response.authResponse.userID;
prefix = 'facebook-' + fbUserId;
S3.config.credentials = new AWS.WebIdentityCredentials({
ProviderId: 'graph.facebook.com',
RoleArn: roleArn,
WebIdentityToken: fbToken
});
userLoggedIn = true;
console.log('Finished creating AWS credentials for account: ' + fbUserId);
syncShoppingList();
}
/******************** Create a new shopping list ***************************/
function createShoppingList(){
if (validLogin()){
var listName = $('#inputCreateName')[0].value;
if (listName == ''){
growl('danger', 'List Name Error', 'Please enter a valid name for your shopping list!');
return;
}
$('#btnCreate').attr("disabled", "disabled");
showSpinner();
data = {
listName: listName,
itemList: $('#inputCreateList')[0].value,
lastUpdated: new Date()
};
var key = prefix + '/' + listName + '.json';
saveLocalStorage(data,key);
var keyDetails = {
'key': key,
'lastUpdated': new Date()
}
objKeys.push(keyDetails);
saveLocalStorage(objKeys,'objKeysBSL');
hideSpinner();
$('#btnCreate').removeAttr("disabled");
loadModals();
growl('success', 'List Created', 'Shopping list successfully created');
}
}
/**************** Delete an existing shopping list ************************/
function deleteShoppingList(shoppingList){
if (objKeys.length>0){
$('#btnDelete').attr("disabled", "disabled");
var key = objKeys[shoppingList].key;
deleteLocalStorage(key);
objKeys.splice(shoppingList, 1);
saveLocalStorage(objKeys,'objKeysBSL');
loadModals();
growl('success','Deleted.','Shopping list successfully deleted');
$('#btnDelete').removeAttr("disabled");
}
else{
growl('danger','Error.','You have no shopping lists to delete!');
}
}
/****************** Read an existing shopping list *************************/
function readShoppingList(shoppingList){
if (objKeys.length>0){
var key = objKeys[shoppingList].key;
$('#inputReadList')[0].innerHTML = readLocalStorage(key).itemList;
}
else{
$('#inputReadList')[0].innerHTML = 'You currently have no shopping lists.'
}
}
/************************* S3 functions ************************************/
function saveS3(data,key){
}
function deleteS3(key){
}
function syncShoppingList(){
}
function checkLocal(){
}
function syncS3Local(objKeyS3, emptyS3){
}
/*********************** Local Storage Functions ***************************/
function saveLocalStorage(data,key){
localStorage.setItem(key, JSON.stringify(data));
}
function readLocalStorage(key){
if (localStorage.getItem(key)){
return JSON.parse(localStorage.getItem(key));
}
}
function deleteLocalStorage(key){
localStorage.removeItem(key);
}
function loadObjKeys(){
// Get objKeys from local storage
console.log('Retrieving database index from local storage...');
objKeys = readLocalStorage('objKeysBSL');
// Check objKeys is null.
try
{
if ((objKeys === null)||(objKeys === undefined))
{
objKeys =[];
}
}
catch (e)
{
// Problem with objKeys
objKeys =[];
}
console.log('Retrieved local objKeys: ' + JSON.stringify(objKeys));
growl('success','Completed','Retrieved database index from local storage... ');
}
/*************************** User Interface ********************************/
function loadModals(){
console.log('load Modals with :'+ JSON.stringify(objKeys))
var tempStr = '';
var option;
var x = $('#dropdownReadList')[0];
var y = $('#dropdownDeleteList')[0];
x.innerHTML = ''; // Clear dropdown lists
y.innerHTML = '';
// Load dropdown lists with object names
for (var a=0; a<objKeys.length;a++){
tempStr = objKeys[a].key.substring(objKeys[a].key.indexOf('/') + 1);
tempStr = tempStr.replace('.json', '');
console.log('load Modals with :'+ tempStr)
option = document.createElement('option');
option.text = tempStr;
x.add(option);
option = document.createElement('option');
option.text = tempStr;
y.add(option);
}
}
function growl(alertType,title,message){
$('#jGrowl-container1').jGrowl({
header: title,
message: message,
group: 'alert-' + alertType,
life: 5000
});
}
function showSpinner(){
$('#pageSpinner').css('display', 'block');
}
function hideSpinner(){
$('#pageSpinner').css('display', 'none');
}
/*************************** END *******************************************/
})();
<!DOCTYPE html>
<html>
<head>
<title>BackSpace Shopping List</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-jgrowl/1.4.3/jquery.jgrowl.min.css" type="text/css"/>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"/>
<link rel="stylesheet" href="app.css"/>
</head>
<body>
<div id="jGrowl-container1" class="jGrowl top-right"></div>
<!-- Main page -->
<div class="container">
<div class="page-header">
<h1 style='color:#ddd'>BackSpace Shopping <small style='color:#eee'>Shopping lists in the Cloud.</small></h1>
</div>
<div class="jumbotron">
<h1>Welcome to the BackSpace Shopping List App</h1>
<p>Create shopping lists anywhere, on any device. Have your shopping lists ready when you are.</p>
<br>
<!-- Facebook Login Button and Status -->
<fb:login-button scope="public_profile,email" onlogin="checkLoginState();" data-size="xlarge">
</fb:login-button>
<div id="status"></div>
<div id="fb-root"></div>
<hr>
<!-- Shopping List Buttons -->
<p>
<button type="button" class="btn btn-success btn-lg" data-toggle="modal" data-target="#createModal">
Create List
</button>
<button type="button" class="btn btn-primary btn-lg" data-toggle="modal" data-target="#readModal">
Read List
</button>
<button type="button" class="btn btn-primary btn-lg" id="btnSync">
Sync with Cloud
</button>
<button type="button" class="btn btn-danger btn-lg" data-toggle="modal" data-target="#deleteModal">
Delete List
</button>
<div id= "pageSpinner" class="alert alert-info" role="alert">
<span class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span> Working, please wait...
</div>
</p>
</div>
</div>
<!-- Create List Modal -->
<div class="modal fade" id="createModal" tabindex="-1" role="dialog" aria-labelledby="createModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="createModalLabel">Create List</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="inputCreateName">Name of List</label>
<input type="text" class="form-control" id="inputCreateName" placeholder="List Name" required>
</div>
<div class="form-group">
<label for="inputCreateList">List of Shopping Items</label>
<textarea class="form-control" rows="15" id="inputCreateList" placeholder="Shopping Items"></textarea>
</div>
<br>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="btnCreate" type="button" class="btn btn-success">Create list</button>
</div>
</div>
</div>
</div>
<!-- Read List Modal -->
<div class="modal fade" id="readModal" tabindex="-1" role="dialog" aria-labelledby="readModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="readModalLabel">Read Shopping List</h4>
</div>
<div class="modal-body">
<div class="dropdown">
<select id="dropdownReadList" class="btn btn-default"></select>
</div>
<div class="form-group">
<label for="inputReadList">List of Shopping Items</label>
<div class="form-control" id="inputReadList"></div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- Delete List Modal -->
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="deleteModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="deleteModalLabel">Delete Shopping List</h4>
</div>
<div class="modal-body">
<div class="dropdown">
<select id="dropdownDeleteList" class="btn btn-default"></select>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button id="btnDelete" type="button" class="btn btn-danger">Delete List</button>
</div>
</div>
</div>
</div>
<!-- External libraries (JQuery, Bootstrap & AWS Javascript SDK) -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.43.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/async/1.4.2/async.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery-jgrowl/1.4.1/jquery.jgrowl.min.js"></script>
<script src="app.js" type="text/javascript"></script>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Privacy Policy</title>
</head>
<body>
<p>Generic Privacy Policy template<br />Privacy Policy<br />Last updated: (add date)<br />My Company (change this) ("us", "we", or "our") operates http://www.mysite.com (change this) (the<br />"Site"). This page informs you of our policies regarding the collection, use and disclosure of<br />Personal Information we receive from users of the Site.<br />We use your Personal Information only for providing and improving the Site. By using the Site, you<br />agree to the collection and use of information in accordance with this policy.<br />Information Collection And Use<br />While using our Site, we may ask you to provide us with certain personally identifiable information<br />that can be used to contact or identify you. Personally identifiable information may include, but is not<br />limited to your name ("Personal Information").<br />Log Data<br />Like many site operators, we collect information that your browser sends whenever you visit our Site<br />("Log Data").<br />This Log Data may include information such as your computer's Internet Protocol ("IP") address,<br />browser type, browser version, the pages of our Site that you visit, the time and date of your visit,<br />the time spent on those pages and other statistics.<br />In addition, we may use third party services such as Google Analytics that collect, monitor and<br />analyze this &hellip;<br />The Log Data section is for businesses that use analytics or tracking services in websites or<br />apps, like Google Analytics. For the full disclosure section, create your own Privacy Policy.<br />Communications<br />We may use your Personal Information to contact you with newsletters, marketing or promotional<br />materials and other information that ...<br />The Communications section is for businesses that may contact users via email (email<br />newsletters) or other methods. For the full disclosure section, create your own Privacy Policy.<br />Cookies<br />Cookies are files with small amount of data, which may include an anonymous unique identifier.<br />Cookies are sent to your browser from a web site and stored on your computer's hard drive.<br />Like many sites, we use "cookies" to collect information. You can instruct your browser to refuse all<br />cookies or to indicate when a cookie is being sent. However, if you do not accept cookies, you may<br />not be able to use some portions of our Site.<br />Security<br />The security of your Personal Information is important to us, but remember that no method of<br />transmission over the Internet, or method of electronic storage, is 100% secure. While we strive to<br />use commercially acceptable means to protect your Personal Information, we cannot guarantee its<br />absolute security.<br />Changes To This Privacy Policy<br />This Privacy Policy is effective as of (add date) and will remain in effect except with respect to any<br />changes in its provisions in the future, which will be in effect immediately after being posted on this<br />page.<br />We reserve the right to update or change our Privacy Policy at any time and you should check this<br />Privacy Policy periodically. Your continued use of the Service after we post any modifications to the<br />Privacy Policy on this page will constitute your acknowledgment of the modifications and your<br />consent to abide and be bound by the modified Privacy Policy.<br />If we make any material changes to this Privacy Policy, we will notify you either through the email<br />address you have provided us, or by placing a prominent notice on our website.<br />Contact Us<br />If you have any questions about this Privacy Policy, please contact us.<br />Create your own Privacy Policy<br />For websites, apps and more. Download as HTML or Text. Unlock premium content.<br />Disclaimer: Legal information is not legal advice. Read the disclaimer.</p>
</body>
</html>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Website usage terms and conditions</title>
</head>
<body>
<h3>Website usage terms and conditions &ndash; sample template</h3>
<p>Welcome to our website. If you continue to browse and use this website, you are agreeing to comply with and be bound by the following terms and conditions of use, which together with our privacy policy govern [business name]&rsquo;s relationship with you in relation to this website. If you disagree with any part of these terms and conditions, please do not use our website.</p>
<p>The term &lsquo;[business name]&rsquo; or &lsquo;us&rsquo; or &lsquo;we&rsquo; refers to the owner of the website whose registered office is [address]. Our company registration number is [company registration number and place of registration]. The term &lsquo;you&rsquo; refers to the user or viewer of our website.</p>
<p>The use of this website is subject to the following terms of use:</p>
<ul>
<li>The content of the pages of this website is for your general information and use only. It is subject to change without notice.</li>
<li>This website uses cookies to monitor browsing preferences. If you do allow cookies to be used, the following personal information may be stored by us for use by third parties: [insert list of information].</li>
<li>Neither we nor any third parties provide any warranty or guarantee as to the accuracy, timeliness, performance, completeness or suitability of the information and materials found or offered on this website for any particular purpose. You acknowledge that such information and materials may contain inaccuracies or errors and we expressly exclude liability for any such inaccuracies or errors to the fullest extent permitted by law.</li>
<li>Your use of any information or materials on this website is entirely at your own risk, for which we shall not be liable. It shall be your own responsibility to ensure that any products, services or information available through this website meet your specific requirements.</li>
<li>This website contains material which is owned by or licensed to us. This material includes, but is not limited to, the design, layout, look, appearance and graphics. Reproduction is prohibited other than in accordance with the copyright notice, which forms part of these terms and conditions.</li>
<li>All trademarks reproduced in this website, which are not the property of, or licensed to the operator, are acknowledged on the website.</li>
<li>Unauthorised use of this website may give rise to a claim for damages and/or be a criminal offence.</li>
<li>From time to time, this website may also include links to other websites. These links are provided for your convenience to provide further information. They do not signify that we endorse the website(s). We have no responsibility for the content of the linked website(s).</li>
<li>Your use of this website and any dispute arising out of such use of the website is subject to the laws of England, Northern Ireland, Scotland and Wales.</li>
</ul>
<p>&nbsp;</p>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment