Skip to content

Commit

Permalink
Everything
Browse files Browse the repository at this point in the history
  • Loading branch information
domfarolino committed May 2, 2023
1 parent b639cb2 commit 83bd15b
Show file tree
Hide file tree
Showing 16 changed files with 3,066 additions and 2 deletions.
Binary file added .DS_Store
Binary file not shown.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GITHUB_CLIENT_ID=FOO
GITHUB_CLIENT_SECRET=FOO
MONGO_URL=mongodb[.....]
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.DS_Store
.env
node_modules
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
# pages
See all repos served with GitHub pages
# pages 👀

See all repos served with GitHub pages for a given user (and their followers).

![home](./imgs/home.png)
31 changes: 31 additions & 0 deletions api/authenticationHelpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Authentication helpers to determine if a user is logged in or not
* before a route returns information to the response
*/

function isAuthOrRedirect(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/');
}

function isNotAuthOrRedirect(req, res, next) {
if (!req.isAuthenticated()) { return next(); }
res.redirect('/');
}

function isAuth(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.status(401).json({"authenticated": false});
}

function isNotAuth(req, res, next) {
if (!req.isAuthenticated()) { return next(); }
res.json({"authenticated": true});
}

module.exports = {
isAuthOrRedirect : isAuthOrRedirect,
isNotAuthOrRedirect : isNotAuthOrRedirect,
isAuth : isAuth,
isNotAuth : isNotAuth
}
59 changes: 59 additions & 0 deletions api/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const authenticationHelpers = require('./authenticationHelpers');
const mongoose = require('mongoose');
const routes = require('express').Router();
const passport = require('passport');

mongoose.connect(process.env.MONGO_URL);
mongoose.connection.on('error', console.error.bind(console, 'connection error:'));
mongoose.connection.once('open', _ => {console.log('Connected to mongoose in API index!')});

/**
* CORS and cache-handling stuff
*/
routes.use('/*', (request, response, next) => {
const origin = request.headers.origin;
const allowedOrigins = [
'http://localhost:8000',
'https://localhost:443',
];

if (allowedOrigins.includes(origin)) {
response.setHeader('Access-Control-Allow-Origin', origin);
response.setHeader('Access-Control-Allow-Headers', 'Content-Type,X-Requested-With');
response.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,HEAD,DELETE,OPTIONS');
response.setHeader('Access-Control-Allow-Credentials', true);
}

// API responses should never be stored
response.set({
'Cache-Control': 'no-store',
});

response.removeHeader('X-Powered-By');
next();
});

// API index handler
routes.get('/', (request, response) => {
response.json({api: true, authenticated: request.isAuthenticated()});
});

// API index handler
routes.get('/github-callback', passport.authenticate('github'), (request, response) => {
console.assert(request.isAuthenticated());
response.redirect(`/?username=${request.user.username}`);
});

// '/api/user/logout'
routes.get('/logout', authenticationHelpers.isAuthOrRedirect, async (request, response, next) => {
request.logout(function(err) {
if (err) { return next(err); }
response.redirect('/');
});
});

// Registration endpoints
const userRoutes = require('./user');
routes.use('/user', userRoutes);

module.exports = routes;
59 changes: 59 additions & 0 deletions api/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const authenticationHelpers = require('./authenticationHelpers');
const crypto = require('crypto');
const GitHubStrategy = require('passport-github2');
const passport = require('passport');
const routes = require('express').Router();
const { User } = require('../models/user');

passport.use(
new GitHubStrategy(
{
clientID: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET
},
async (accessToken, refreshToken, profile, done) => {
const user = await User.findOne({githubId: profile.id});
if (user) {
user.githubId = profile.id;
user.displayName = profile.displayName;
user.username = profile.username;
user.email = profile.emails[0].value;
await user.save();
return done(null, user);
}

try {
const savedUser = await new User({
githubId: profile.id,
displayName: profile.displayName,
username: profile.username,
email: profile.emails[0].value,
accessToken,
}).save();

done(null, savedUser);
} catch (e) {
done(e);
}
} // async function
)
);

passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((obj, done) => {
done(null, obj);
});

///////////////////////////////

// '/api/user/logout'
routes.get('/logout', authenticationHelpers.isAuthOrRedirect, async (request, response, next) => {
request.logout(function(err) {
if (err) { return next(err); }
response.redirect('/');
});
});

module.exports = routes;
Binary file added imgs/home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 54 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require('dotenv').config();

const authenticationHelpers = require('./api/authenticationHelpers');
const cookieParser = require('cookie-parser');
const ejs = require('ejs');
const express = require('express');
const fs = require('fs');
const https = require('https');
const http = require('http');
const logger = require('morgan');
const path = require('path');
const passport = require('passport');
const session = require('express-session');
const {User} = require('./models/user');

const kPort = 8000;
const app = express();

// Note: This must come before the subsequent `app.use()`s.
app.use(logger('dev'));
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, './public'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(session({
secret: 'secret-here',
resave: false,
saveUninitialized: true,
cookie: {
maxAge: 60 * 60 * 1000, // 1 hour
secure: false,
httpOnly: true,
}
}));
app.use(passport.initialize());
app.use(passport.session());

/**
* API setup
*/
const server = http.createServer({}, app);

server.listen(kPort, () => {
console.log(`Server starting on port ${kPort}`);
});

app.get('/', (request, response) => {
response.render('index', {isAuthenticated: request.isAuthenticated(), accessToken: request.isAuthenticated() ? request.user.accessToken : undefined});
});
app.use('/', express.static('public'))

const api = require('./api');
app.use('/api', api);
34 changes: 34 additions & 0 deletions models/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const crypto = require('crypto');
const mongoose = require('mongoose');

const userScheme = mongoose.Schema({
githubId: {
type: String,
required: true,
unique: true,
},
displayName: {
type: String,
required: true,
unique: false,
},
username: {
type: String,
required: true,
unique: true,
},
email: {
type: String,
required: true,
unique: true,
},
accessToken: {
type: String,
required: true,
unique: true,
},
});

const User = mongoose.model('User', userScheme);

module.exports = {User};
Loading

0 comments on commit 83bd15b

Please sign in to comment.