diff --git a/server.js b/server.js index d049dec..a656503 100644 --- a/server.js +++ b/server.js @@ -1,6 +1,4 @@ -const path = require('path'); const express = require('express'); -const cookieSession = require('cookie-session'); require('dotenv').config(); const ForgeSDK = require('forge-apis'); @@ -13,93 +11,95 @@ const ForgeSDK = require('forge-apis'); https://forge.autodesk.com/blog/3legged-token-process-nodejs-cli Server running on port 3000 used to get 3-legged access token. - Must have FORGE_CLIENT_ID, FORGE_CLIENT_SECRET, and FORGE_CALLBACK_URL set in .env file. - FORGE_CALLBACK_URL (should be 'http://localhost:3000/callback/') should be the same in the .env - and in the Forge API project console. + Must have FORGE_CLIENT_ID, FORGE_CLIENT_SECRET, and FORGE_CALLBACK_URL set in .env file. + FORGE_CALLBACK_URL (should be 'http://localhost:3000/callback/') should be the same in the .env + and in the Forge API project console. - Usage: node test.js or npm start - Navigate to http://localhost:3000/auth/ to get started - Browser should then go through the Autodesk Auth screen and display Auth token. + Usage: node test.js or npm start + Navigate to http://localhost:3000/auth/ to get started + Browser should then go through the Autodesk Auth screen and display Auth token. */ + const scopes = ['bucket:create', 'bucket:read', 'data:read', 'data:create', 'data:write']; -var oAuth2ThreeLegged = new ForgeSDK.AuthClientThreeLegged( - process.env.FORGE_CLIENT_ID, - process.env.FORGE_CLIENT_SECRET, - process.env.FORGE_CALLBACK_URL, - scopes, - true +const oAuth2ThreeLegged = new ForgeSDK.AuthClientThreeLegged( + process.env.FORGE_CLIENT_ID, + process.env.FORGE_CLIENT_SECRET, + process.env.FORGE_CALLBACK_URL, + scopes, + true ); -var credentials; - -/* - Function to start the server - TODO: return both the oAuth2ThreeLegged and credentials objects, these will be needed for other API wrappers -*/ -function createServer() { - const app = express(); - const PORT = process.env.PORT || 3000; - - if (process.env.FORGE_CLIENT_ID == null || process.env.FORGE_CLIENT_SECRET == null) { - console.error('Missing FORGE_CLIENT_ID or FORGE_CLIENT_SECRET env. variables.'); - return; - } - - app.use(express.static(path.join(__dirname, 'public'))); - app.use(cookieSession({ - name: 'forge_session', - keys: ['forge_secure_key'], - maxAge: 14 * 24 * 60 * 60 * 1000 // 14 days, same as refresh token - })); - - // Endpoint to begin authentication process - app.get('/auth', function (req, res) { - res.redirect(oAuth2ThreeLegged.generateAuthUrl()); - }); - - // Endpoint Forge redirects to after consent screen - app.get('/callback', function (req, res) { - oAuth2ThreeLegged.getToken(req.query.code).then((credentials) => { - setCredentials(credentials) - res.send("Generated token: " + credentials.access_token) - }, (err) => { - console.error(err); - res.send('Failed to authenticate'); - }); - }); - - app.use((err, req, res, next) => { - console.error(err); - res.status(err.statusCode).json(err); - }); - - const server = app.listen(PORT, () => { console.log(`Server listening on port ${PORT}`); }); - - return server; -} - -const setCredentials = (cr) => { - credentials = cr -} - -const getCredentials = () => { - return credentials -} - -/* - Function to shutdown the server -*/ -function shutdownServer(server) { - server.close(() => { - console.log('Closing connections'); - return; - }); +let credentials = null; +let refreshTime = null; + +/** + * Creates server with three endpoints: + * 1. /auth + * - navigate to login in to Autodesk and begin auth process + * 2. /callback + * - after consent screen, auth API will redirect headers + * 3. /credentials + * - will return credentials JSON object or null if there isn't one + * @returns server object + */ +function createServer () { + const app = express(); + const PORT = process.env.PORT || 3000; + + if (process.env.FORGE_CLIENT_ID == null || process.env.FORGE_CLIENT_SECRET == null) { + console.error('Missing FORGE_CLIENT_ID or FORGE_CLIENT_SECRET env. variables.'); + return; + } + + // Endpoint to begin authentication process + app.get('/auth', function (req, res) { + res.redirect(oAuth2ThreeLegged.generateAuthUrl()); + }); + + // Endpoint Forge redirects to after consent screen + app.get('/callback', function (req, res) { + oAuth2ThreeLegged.getToken(req.query.code) + .then((creds) => { + credentials = creds; + refreshTime = creds.expires_in - 300; + res.send('Generated token: ' + credentials.access_token); + }) + .then(() => { + setInterval(() => refresh(), refreshTime * 1000); // seconds to ms + console.log(credentials); + }) + .catch((err) => { + console.error(err); + res.send('Failed to authenticate'); + }); + }); + + // Endpoint for internal use, to get credentials from our auth server + app.get('/credentials', function (req, res) { + res.send(credentials); + }); + + app.use((err, req, res, next) => { + console.error(err); + res.status(err.statusCode).json(err); + }); + + const server = app.listen(PORT, () => { console.log(`Server listening on port ${PORT}`); }); + + return server; } -module.exports = { - create: createServer, - shutdown: shutdownServer, - authClient: oAuth2ThreeLegged, - getCredentials: getCredentials -} \ No newline at end of file +/** + * Used to refresh tokens + */ +const refresh = () => { + oAuth2ThreeLegged.refreshToken(credentials, scopes) + .then(creds => { + credentials = creds; + console.log('new token generated from refresh token'); + console.log(credentials); + }); +}; + +createServer(); diff --git a/test.js b/test.js index 52b3765..cc5486c 100644 --- a/test.js +++ b/test.js @@ -19,54 +19,60 @@ var BucketsApi = new ForgeSDK.BucketsApi(); //Buckets Client var FoldersApi = new ForgeSDK.FoldersApi(); var ObjectsApi = new ForgeSDK.ObjectsApi(); -async function waitUntil(hasCredentials) { - return await new Promise(resolve => { - const interval = setInterval(() => { - console.log('Running every 5 sec, waiting for browser authorization at localhost:3000/auth'); - hasCredentials = authServer.getCredentials(); - if (hasCredentials != undefined) { - credentials = hasCredentials; - console.log(credentials) - fs.writeFile("credentials.json", JSON.stringify(credentials), err => { - if (err) { - throw err; - } - console.log("credentials file written") - }) - resolve('credentials recieved'); - clearInterval(interval); - }; - }, 5000); - }); -} +// Define constants for file sync folders/project +const projectID = "a.YnVzaW5lc3M6cHVyZHVlMjY5NiMyMDIxMTEwODQ2NDQzMzk3Ng"; + + +// async function waitUntil(hasCredentials) { +// return await new Promise(resolve => { +// const interval = setInterval(() => { +// console.log('Running every 5 sec, waiting for browser authorization at localhost:3000/auth'); +// hasCredentials = authServer.getCredentials(); +// if (hasCredentials != undefined) { +// credentials = hasCredentials; +// // console.log(credentials) +// process.env.CREDENTIALS = JSON.stringify(credentials); +// fs.writeFile("credentials.json", JSON.stringify(credentials), err => { +// if (err) { +// throw err; +// } +// console.log("credentials file written") +// }) +// resolve('credentials recieved'); +// clearInterval(interval); +// }; +// }, 5000); +// }); +// } (async () => { - var content = null; + // var content = null; - var data = await fs.readFile("credentials.json", 'ascii'); + // var data = await fs.readFile("credentials.json", 'ascii'); - // Converting to JSON - content = await JSON.parse(data); - // console.log(Object.keys(content).length) + // // Converting to JSON + // content = await JSON.parse(data); + // // console.log(Object.keys(content).length) - if (Object.keys(content).length == 0) { - // create the server - let server = await authServer.create(); + // if (Object.keys(content).length == 0) { + // // create the server + // let server = await authServer.create(); - // wait until user authenticates through browser - await waitUntil(hasCredentials); + // // wait until user authenticates through browser + // await waitUntil(hasCredentials); - // cannot shutdown the server becuase it is running on the same thread, doing this will just kill the node process (i.e. test.js) - // authServer.shutdown(server); - } + // // cannot shutdown the server becuase it is running on the same thread, doing this will just kill the node process (i.e. test.js) + // // authServer.shutdown(server); + // } - credentials = fileCreds; + // Object.keys(fileCreds).length == 0 ? credentials = hasCredentials : credentials = fileCreds; console.log("Authenticated"); // console.log(credentials); // console.log(authClient); + console.log(JSON.parse(process.env.CREDENTIALS)); // Can do use forge APIs now, using credentials and authClient @@ -78,23 +84,23 @@ async function waitUntil(hasCredentials) { const adminProjectID = 'a.YnVzaW5lc3M6cHVyZHVlMjY5NiMyMDIxMTEwODQ2NDQzMzk3Ng'; const adminProjectTopFolder = 'urn:adsk.wipprod:fs.folder:co.ltuYad4ZTtieJLm6j3MGuA'; - HubsApi.getHubs({}, authClient, credentials).then(function(hubs) { - // console.log(hubs.body.data); - }, function(err) { - console.error(err); - }); - - ProjectsApi.getHubProjects(gavinHubID, {}, authClient, credentials).then(function(projects) { - // console.log(projects.body.data); - }, function(err) { - console.log(err) - }) - - ProjectsApi.getProjectTopFolders(gavinHubID, adminProjectID, authClient, credentials).then(function(folders) { - // console.log(folders.body.data); - }, function(err) { - console.log(err) - }) + // HubsApi.getHubs({}, authClient, credentials).then(function(hubs) { + // console.log(hubs.body.data); + // }, function(err) { + // console.log(err); + // }); + + // ProjectsApi.getHubProjects(gavinHubID, {}, authClient, credentials).then(function(projects) { + // console.log(projects.body.data); + // }, function(err) { + // console.log(err) + // }) + + // ProjectsApi.getProjectTopFolders(gavinHubID, adminProjectID, authClient, credentials).then(function(folders) { + // console.log(folders.body.data); + // }, function(err) { + // console.log(err) + // }) var obj;