| @ -0,0 +1,7 @@ | |||
| ```bash | |||
| npm install fs --save | |||
| npm install unirest --save | |||
| npm install express --save | |||
| npm install passport --save | |||
| npm install passport-fitbit-oauth2 --save | |||
| ``` | |||
| @ -0,0 +1,6 @@ | |||
| { | |||
| "port": 9000, | |||
| "clientID": "fit bit client id", | |||
| "clientSecret": "super secret", | |||
| "callbackURL": "https://jrtechs.student.rit.edu/auth/fitbit/callback" | |||
| } | |||
| @ -0,0 +1,70 @@ | |||
| <!DOCTYPE html> | |||
| <html lang="en"> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>Title</title> | |||
| <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> | |||
| </head> | |||
| <body> | |||
| <div class="row"> | |||
| <div class="col col-md-6 col-12"> | |||
| <script type='text/javascript' src='https://darksky.net/widget/graph-bar/43.1573,-77.6152/us12/en.js?width=100%&height=400&title=Full Forecast&textColor=333333&bgColor=transparent&transparency=true&skyColor=undefined&fontFamily=Default&customFont=&units=us&timeColor=333333&tempColor=333333¤tDetailsOption=true'></script> | |||
| <script type='text/javascript' src='https://darksky.net/widget/default/43.1573,-77.6152/us12/en.js?width=100%&height=350&title=Rochester NY&textColor=333333&bgColor=transparent&transparency=true&skyColor=undefined&fontFamily=Default&customFont=&units=us&htColor=333333<Color=C7C7C7&displaySum=yes&displayHeader=yes'></script> | |||
| </div> | |||
| <div class="col col-md-6 col-12"> | |||
| <!-- start sw-rss-feed code --> | |||
| <script type="text/javascript"> | |||
| rssfeed_url = new Array(); | |||
| rssfeed_url[0]="https://news.google.com/news/rss"; | |||
| rssfeed_frame_width="100%"; | |||
| rssfeed_frame_height="260"; | |||
| rssfeed_scroll="off"; | |||
| rssfeed_scroll_step="20"; | |||
| rssfeed_scroll_bar="on"; | |||
| rssfeed_target="_blank"; | |||
| rssfeed_font_size="12"; | |||
| rssfeed_font_face=""; | |||
| rssfeed_border="on"; | |||
| rssfeed_css_url=""; | |||
| rssfeed_title="on"; | |||
| rssfeed_title_name=""; | |||
| rssfeed_title_bgcolor="#3366ff"; | |||
| rssfeed_title_color="#fff"; | |||
| rssfeed_title_bgimage=""; | |||
| rssfeed_footer="off"; | |||
| rssfeed_footer_name="rss feed"; | |||
| rssfeed_footer_bgcolor="#fff"; | |||
| rssfeed_footer_color="#333"; | |||
| rssfeed_footer_bgimage=""; | |||
| rssfeed_item_title_length="50"; | |||
| rssfeed_item_title_color="#666"; | |||
| rssfeed_item_bgcolor="#fff"; | |||
| rssfeed_item_bgimage=""; | |||
| rssfeed_item_border_bottom="on"; | |||
| rssfeed_item_source_icon="off"; | |||
| rssfeed_item_date="off"; | |||
| rssfeed_item_description="on"; | |||
| rssfeed_item_description_length="120"; | |||
| rssfeed_item_description_color="#666"; | |||
| rssfeed_item_description_link_color="#333"; | |||
| rssfeed_item_description_tag="off"; | |||
| rssfeed_no_items="0"; | |||
| rssfeed_cache = "2220318b43254a73f6fcdb3732f0e710"; | |||
| </script> | |||
| <script type="text/javascript" src="//feed.surfing-waves.com/js/rss-feed.js"></script> | |||
| <!-- The link below helps keep this service FREE, and helps other people find the SW widget. Please be cool and keep it! Thanks. --> | |||
| <div style="color:#ccc;font-size:10px; text-align:right; width:100%;">powered by <a href="https://surfing-waves.com" rel="noopener" target="_blank" style="color:#ccc;">Surfing Waves</a></div> | |||
| <!-- end sw-rss-feed code --> | |||
| </div> | |||
| </div> | |||
| </body> | |||
| </html> | |||
| @ -0,0 +1,95 @@ | |||
| /** express app */ | |||
| const express = require("express"); | |||
| /** Manages oauth 2.0 w/ fitbit */ | |||
| const passport = require('passport'); | |||
| /** Used to make API calls */ | |||
| const unirest = require('unirest'); | |||
| /** express app */ | |||
| const app = express(); | |||
| /** pull config file */ | |||
| const utils = require("./utils.js"); | |||
| const config = utils.getFileAsJSON("config.json"); | |||
| app.use(passport.initialize()); | |||
| app.use(passport.session({ | |||
| resave: false, | |||
| saveUninitialized: true | |||
| })); | |||
| var FitbitStrategy = require( 'passport-fitbit-oauth2' ).FitbitOAuth2Strategy; | |||
| var accessTokenTemp = null; | |||
| passport.use(new FitbitStrategy({ | |||
| clientID: config.clientID, | |||
| clientSecret: config.clientSecret, | |||
| callbackURL: config.callbackURL | |||
| }, | |||
| function(accessToken, refreshToken, profile, done) | |||
| { | |||
| console.log(accessToken); | |||
| accessTokenTemp = accessToken; | |||
| done(null, { | |||
| accessToken: accessToken, | |||
| refreshToken: refreshToken, | |||
| profile: profile | |||
| }); | |||
| } | |||
| )); | |||
| passport.serializeUser(function(user, done) { | |||
| done(null, user); | |||
| }); | |||
| passport.deserializeUser(function(obj, done) { | |||
| done(null, obj); | |||
| }); | |||
| passport.authenticate('fitbit', { scope: ['activity','heartrate','location','profile'] }); | |||
| app.get('/auth/fitbit', | |||
| passport.authenticate('fitbit', { scope: ['activity','heartrate','location','profile'] } | |||
| )); | |||
| app.get( '/auth/fitbit/callback', passport.authenticate( 'fitbit', { | |||
| successRedirect: '/', | |||
| failureRedirect: '/error' | |||
| })); | |||
| app.get('/error', (request, result) => | |||
| { | |||
| result.write("Error authenticating with Fitbit API"); | |||
| result.end(); | |||
| }); | |||
| app.get('/', (request, result) => | |||
| { | |||
| if(accessTokenTemp == null) | |||
| { | |||
| result.redirect('/auth/fitbit'); | |||
| } | |||
| unirest.get('https://api.fitbit.com/1/user/-/activities/steps/date/today/1m.json') | |||
| .headers({'Accept': 'application/json', 'Content-Type': 'application/json', Authorization: "Bearer " + accessTokenTemp}) | |||
| .end(function (response) | |||
| { | |||
| // result.write(response.body); | |||
| result.end(); | |||
| console.log(response.body); | |||
| }); | |||
| }); | |||
| app.listen(PORT, () => | |||
| console.log(`App listening on port ${config.port}!`) | |||
| ); | |||
| @ -0,0 +1,20 @@ | |||
| const fs = require('fs'); | |||
| module.exports= | |||
| { | |||
| /** | |||
| * | |||
| * @param fileName | |||
| * @returns {any} | |||
| */ | |||
| getFileAsJSON: function(fileName) | |||
| { | |||
| return JSON.parse(module.exports.getFile(fileName)); | |||
| }, | |||
| getFile: function(filename) | |||
| { | |||
| return fs.readFileSync(filename, 'utf8'); | |||
| } | |||
| }; | |||