diff --git a/app.js b/app.js
index 2069cc0a..b549ebbc 100644
--- a/app.js
+++ b/app.js
@@ -1,17 +1,19 @@
-var mongoose = require("mongoose");
-var createError = require("http-errors");
-var express = require("express");
-var exphbs = require("express-handlebars");
-var path = require("path");
-var cookieParser = require("cookie-parser");
-var logger = require("morgan");
-var session = require("express-session");
-var flash = require("connect-flash");
-var MongoStore = require("connect-mongo")(session);
-require("dotenv").config();
-require("./schedule");
-const passport = require("passport");
-const fx = require("money");
+var mongoose = require('mongoose');
+var createError = require('http-errors');
+var express = require('express');
+var exphbs = require('express-handlebars');
+var path = require('path');
+var cookieParser = require('cookie-parser');
+var logger = require('morgan');
+var session = require('express-session');
+var flash = require('connect-flash');
+var MongoStore = require('connect-mongo')(session);
+require('dotenv').config();
+require('./schedule');
+const passport = require('passport');
+const fx = require('money');
+var bodyParser = require('body-parser')
+
// The database setup
// we should probable store the url in .env for security reasons.
@@ -31,7 +33,9 @@ db.once("open", () => console.log("Connected to database"));
// checks if connection to db is a success
db.on("error", console.error.bind(console, "Database connection error:"));
-var indexRouter = require("./routes/index");
+var indexRouter = require('./routes/index');
+var authRouter = require('./routes/auth');
+
// var usersRouter = require('./routes/users');
var app = express();
@@ -80,7 +84,7 @@ app.use(function(req, res, next) {
});
app.use("/", indexRouter);
-// app.use("/auth.js", authRouter);
+app.use("/auth", authRouter);
// app.use('/users', usersRouter);
// catch 404 and forward to error handler
diff --git a/config/passport.js b/config/passport.js
index 0ff14d68..51555f45 100644
--- a/config/passport.js
+++ b/config/passport.js
@@ -47,9 +47,9 @@ module.exports = function(passport) {
// asynchronous
process.nextTick(function() {
-
+
// find the user in the database based on their facebook id
- User.findOne({ 'facebook.id' : profile.id }, function(err, user) {
+ User.findOne({ 'account._id' : `${profile.id}` }, function(err, user) {
// if there is an error, stop everything and return that
// ie an error connecting to the database
@@ -64,18 +64,19 @@ module.exports = function(passport) {
let newUser = new User();
// set all of the facebook information in our user model
- newUser.facebook.id = profile.id; // set the users facebook id
- newUser.facebook.token = token; // we will save the token that facebook provides to the user
- newUser.facebook.name = profile.name.givenName + ' ' + profile.name.familyName; // look at the passport user profile to see how names are returned
- newUser.facebook.email = profile.emails[0].value; // facebook can return multiple emails so we'll take the first
+ newUser.account._id = profile.id; // set the users facebook id
+ newUser.account.token = token; // we will save the token that facebook provides to the user
+ newUser.account.name = profile.name.givenName + ' ' + profile.name.familyName; // look at the passport user profile to see how names are returned
+ newUser.account.email = profile.emails[0].value; // facebook can return multiple emails so we'll take the first
+ newUser.account.type = "facebook";
// save our user to the database
newUser.save(function(err) {
if (err)
throw err;
-
- // if successful, return the new user
- return done(null, newUser);
+ else
+ req.session.user = newUser.account;
+ res.redirect('/job-preference');
});
}
@@ -101,7 +102,7 @@ module.exports = function(passport) {
process.nextTick(function() {
// try to find the user based on their google id
- User.findOne({ 'google.id' : profile.id}, function(err, user){
+ User.findOne({ 'account._id': `${profile.id}`}, function(err, user){
if (err)
return done(err);
@@ -113,11 +114,12 @@ module.exports = function(passport) {
var newUser =new User();
//set all of the relevant information
- newUser.google = {
+ newUser.account = {
id:profile.id,
token:token,
name:profile.displayName,
- email:profile.emails[0].value
+ email:profile.emails[0].value,
+ type: "google"
}
// newUser.google.id = profile.id;
// newUser.google.token = token;
@@ -128,8 +130,10 @@ module.exports = function(passport) {
//save the user
newUser.save(function(err){
if (err)
- throw err;
- return done(null, newUser);
+ throw err;
+ else
+ req.session.user = newUser.account;
+ res.redirect('/job-preference');
});
}
});
diff --git a/controllers/auth.js b/controllers/auth.js
new file mode 100644
index 00000000..076ba841
--- /dev/null
+++ b/controllers/auth.js
@@ -0,0 +1,84 @@
+// Web application which authenticates to github
+var http = require('http')
+ , url = require('url')
+ , qs = require('querystring')
+ , github = require('octonode')
+ , session = require('express-session');
+
+let User = require('../models/login');
+
+// Build the authorization config and url
+var auth_url = github.auth.config({
+ id: process.env.GITHUB_CLIENTID,
+ secret: process.env.GITHUB_SECRET,
+}).login(['user']);
+
+// Store info to verify against CSRF
+var state = auth_url.match(/&state=([0-9a-z]{32})/i);
+
+// Handle github authentication
+exports.authenticate = function (req, res) {
+ res.writeHead(302, { 'Content-Type': 'text/plain', 'Location': auth_url })
+ res.end('Redirecting to ' + auth_url);
+};
+
+// Handle callback
+exports.callback = function (req, res) {
+ var sessData = req.session;
+ uri = url.parse(req.url);
+ var values = qs.parse(uri.query);
+ // Check against CSRF attacks
+ if (!state || state[1] != values.state) {
+
+ res.redirect('/login');
+ } else {
+ github.auth.login(values.code, function (err, token, headers) {
+
+ var client = github.client(token);
+
+ sessData.token = token;
+
+ client.get('/user', {}, function (err, status, body, headers) {
+
+ // find the user in the database based on their github account id
+ User.findOne
+ ({
+ 'account._id': `${body.id}`
+ }, function (err, user) {
+
+ // if there is an error, stop everything and return that
+ // ie an error connecting to the database
+ if (err)
+ res.redirect("/login");
+
+ // if the user is found, then log them in
+ if (user) {
+ req.session.user = user.account;
+ res.redirect("/jobs"); // user found, return that user
+ } else {
+ // if there is no user found with that github id, create them
+ let newUser = new User();
+
+ // set all of the github information in our user model
+ newUser.account._id = `${body.id}`;
+ newUser.account.token = token;
+ newUser.account.name = (body.name == null)? body.login : body.name;
+ newUser.account.email = body.email;
+ newUser.account.type = "github";
+
+ // save our user to the database
+ newUser.save(function (err) {
+ if (err)
+ throw err;
+ else
+ req.session.user = newUser.account;
+ res.redirect('/job-preference');
+ });
+ }
+
+ });
+
+ });
+ });
+ }
+};
\ No newline at end of file
diff --git a/controllers/controllers.js b/controllers/controllers.js
index f9669465..02d5b0e2 100644
--- a/controllers/controllers.js
+++ b/controllers/controllers.js
@@ -7,6 +7,7 @@ const {
sendMailForRemoteJob
} = require("./user");
const userModel = require("../models/user");
+const preferenceModel = require("../models/preferences")
const validateRegisteredUser = require("../validation/registeredUser");
const registeredUsers = require("../models/registeredUsers");
const agentModel = require("../models/newAgent");
@@ -28,7 +29,7 @@ const getData = async () => {
try {
const response = await fetch("https://jobs.github.com/positions.json?location=remote");
const json = await response.json();
-
+
// Parse and produce unique slug -- custom-url
json.forEach(element => {
let title = element.title;
@@ -64,7 +65,7 @@ function search_common(needle, haystack) {
const Jobs = {
async fetchData(req, res) {
-
+
let main = JSON.parse(JSON.stringify(remote_jobs));
if (req.query.country) {
@@ -79,37 +80,37 @@ const Jobs = {
},
async create_registered_user(req, res) {
- const { errors, isValid } = validateRegisteredUser(req.body);
-
- // Check Validation
- if (!isValid) {
- return res.status(400).json(errors);
- }
-
- const queryText = {
- first_name: req.body.first_name,
- last_name: req.body.last_name,
- email: req.body.email,
- phone_number: req.body.phone_number,
- prefered_job_role: req.body.prefered_job_role,
- prefered_job_level: req.body.prefered_job_level,
- prefered_job_type: req.body.prefered_job_type,
- prefered_job_location: req.body.prefered_job_location,
- prefered_job_stack: req.body.prefered_job_stack,
- prefered_update_type: req.body.prefered_update_type,
- prefered_update: req.body.prefered_update,
- created_At: Date.now()
- };
- try {
- let user = await registeredUsers.create(queryText);
- return res.status(200).json({
- status: 'success',
- message: user,
- });
- } catch (error) {
- return res.status(500).send(error);
- }
- },
+ const { errors, isValid } = validateRegisteredUser(req.body);
+
+ // Check Validation
+ if (!isValid) {
+ return res.status(400).json(errors);
+ }
+
+ const queryText = {
+ first_name: req.body.first_name,
+ last_name: req.body.last_name,
+ email: req.body.email,
+ phone_number: req.body.phone_number,
+ prefered_job_role: req.body.prefered_job_role,
+ prefered_job_level: req.body.prefered_job_level,
+ prefered_job_type: req.body.prefered_job_type,
+ prefered_job_location: req.body.prefered_job_location,
+ prefered_job_stack: req.body.prefered_job_stack,
+ prefered_update_type: req.body.prefered_update_type,
+ prefered_update: req.body.prefered_update,
+ created_At: Date.now()
+ };
+ try {
+ let user = await registeredUsers.create(queryText);
+ return res.status(200).json({
+ status: 'success',
+ message: user,
+ });
+ } catch (error) {
+ return res.status(500).send(error);
+ }
+ },
async view_all_registered_users(req, res) {
try {
@@ -122,65 +123,66 @@ const Jobs = {
async update_registered_user(req, res) {
const { _id } = req.params;
- const { errors, isValid } = validateRegisteredUser(req.body);
-
- // Check Validation
- if (!isValid) {
- return res.status(400).json(errors);
- }
-
- const queryText = {
- first_name: req.body.first_name,
- last_name: req.body.last_name,
- email: req.body.email,
- phone_number: req.body.phone_number,
- prefered_job_role: req.body.prefered_job_role,
- prefered_job_level: req.body.prefered_job_level,
- prefered_job_type: req.body.prefered_job_type,
- prefered_job_location: req.body.prefered_job_location,
- prefered_job_stack: req.body.prefered_job_stack,
- prefered_update_type: req.body.prefered_update_type,
- prefered_update: req.body.prefered_update,
- created_At: Date.now()
- };
- try {
-
- let user = await registeredUsers.findOneAndUpdate(_id, queryText)
- return res.status(200).json({
- status: 'success',
- message: user,
- });
- } catch (error) {
- return res.status(500).send(error);
- }
- },
+ const { errors, isValid } = validateRegisteredUser(req.body);
- async fetchPreferredJobs(req, res) {
+ // Check Validation
+ if (!isValid) {
+ return res.status(400).json(errors);
+ }
+
+ const queryText = {
+ first_name: req.body.first_name,
+ last_name: req.body.last_name,
+ email: req.body.email,
+ phone_number: req.body.phone_number,
+ prefered_job_role: req.body.prefered_job_role,
+ prefered_job_level: req.body.prefered_job_level,
+ prefered_job_type: req.body.prefered_job_type,
+ prefered_job_location: req.body.prefered_job_location,
+ prefered_job_stack: req.body.prefered_job_stack,
+ prefered_update_type: req.body.prefered_update_type,
+ prefered_update: req.body.prefered_update,
+ created_At: Date.now()
+ };
try {
- let id = req.params._id;
- if (typeof id == "undefined")
- id = "5ccef761e415f84678d393f1";
- let registeredUser = await registeredUsers.findById(id);
- if (registeredUser != null) {
- let RoleData = ["App Developer", "Database Administrator", "Programmer", "Software Developer", "Web Developer"];
- let LevelData = ["Junior", "Intermediate", "Semior","Intern"]
- let TypeData = ["Part time", "Full time", "Remote", "Part time remote"];
- let LocationData = await fetch(`https://gist.githubusercontent.com/Shock451/53fe61b951f809f8fa91bab6c490aae4/raw/ce8f86dd5606dc59fd966e82ac804580f75082ac/countries.json`);
- let StackData = await fetch(`https://gist.githubusercontent.com/Shock451/4a14fc459f411b0fbbeeb62f6a7ad297/raw/284e5bedbb84ef15f79add3384a2375163d89535/languages.json`);
- let Locations = await LocationData.json();
- let Stacks = await StackData.json();
- //let TotalJobs = RoleJobs.concat(LevelJobs, TypeJobs, LocationJobs, StackJobs);
- // sendPreferedMailForRemoteJob(RoleJobs, registeredUser);
-
-
- return res.status(200).render("jobPreference", {
- RoleData,
- LevelData,
- TypeData,
- Locations: Locations.countries,
- Stacks: Stacks.languages,
+
+ let user = await registeredUsers.findOneAndUpdate(_id, queryText)
+ return res.status(200).json({
+ status: 'success',
+ message: user,
});
+ } catch (error) {
+ return res.status(500).send(error);
}
+ },
+
+ async fetchPreferredJobs(req, res) {
+ try {
+ let id = req.params._id;
+ if (typeof id == "undefined")
+ id = "5ccef761e415f84678d393f1";
+ let registeredUser = await registeredUsers.findById(id);
+ if (registeredUser != null) {
+ let RoleData = ["App Developer", "Database Administrator", "Programmer", "Software Developer", "Web Developer"];
+ let LevelData = ["Junior", "Intermediate", "Semior","Intern"]
+ let TypeData = ["Part time", "Full time", "Remote", "Part time remote"];
+ let LocationData = await fetch(`https://gist.githubusercontent.com/Shock451/53fe61b951f809f8fa91bab6c490aae4/raw/ce8f86dd5606dc59fd966e82ac804580f75082ac/countries.json`);
+ let StackData = await fetch(`https://gist.githubusercontent.com/Shock451/4a14fc459f411b0fbbeeb62f6a7ad297/raw/284e5bedbb84ef15f79add3384a2375163d89535/languages.json`);
+ let Locations = await LocationData.json();
+ let Stacks = await StackData.json();
+ //let TotalJobs = RoleJobs.concat(LevelJobs, TypeJobs, LocationJobs, StackJobs);
+ // sendPreferedMailForRemoteJob(RoleJobs, registeredUser);
+
+
+ return res.status(200).render("jobPreference", {
+ RoleData,
+ LevelData,
+ TypeData,
+ Locations: Locations.countries,
+ Stacks: Stacks.languages,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user
+ });
+ }
return res.status(400).json({
status: "invalid input",
message: "no such user",
@@ -192,6 +194,109 @@ const Jobs = {
}
},
+ async setPreferences(req, res) {
+
+ const queryText = {
+ _id: req.session.user._id
+ };
+
+ let existing_preferences = [];
+
+ let stacks = ["c", "android", "asp", "cplusplus", "java", "javascript", "linux", "node", "php", "python", "react", "ruby", "sql"];
+
+ let types = ["full-time", "part-time", "contract"];
+
+ let frequencies = ["daily", "weekly", "monthly"];
+
+ try {
+ existing_preferences = await preferenceModel.findOne(queryText);
+ if (!existing_preferences) {
+ // create new prefs for user
+ const createText = {
+ _id: req.session.user._id,
+ stacks: [],
+ job_types: [],
+ mail_frequency: "daily" // by default
+ };
+
+ let createdPreferences = await preferenceModel.create(createText);
+ if (!createdPreferences)
+ res.status(400).redirect("/");
+ existing_preferences = createdPreferences;
+ }
+ } catch (err) {
+ throw (err)
+ }
+
+ res.render("jobPreference.hbs", {
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user,
+ job_types: existing_preferences.job_types,
+ stacks: existing_preferences.stacks,
+ frequency: existing_preferences.mail_frequency,
+ helpers:
+ {
+ // this helps with displaying the page links, I guess
+ populate_stacks: function () {
+ parsedhtml = "";
+ for (let i = 0; i < stacks.length; i++) {
+ parsedhtml += `
+
+
+
+ `;
+ }
+ return parsedhtml;
+ },
+ populate_types: function () {
+ parsedhtml = "";
+ for (let i = 0; i < types.length; i++) {
+ parsedhtml += `
+
+
+
+ `;
+ }
+ return parsedhtml;
+ },
+ show_frequencies: function () {
+ parsedhtml = "";
+ for (let i = 0; i < frequencies.length; i++) {
+ parsedhtml += `
+
+
+
+
`;
+ }
+ return parsedhtml;
+ },
+
+ }
+ });
+ },
+
+ async updatePreferences(req, res) {
+ let data = req.body;
+ const queryText = {
+ _id: req.session.user._id
+ };
+ const updateText = {
+ id: req.session.user._id,
+ stacks: data.stacks,
+ job_types: data.categories,
+ mail_frequency: data.frequency
+ };
+ try {
+ let updatedPreferences = await preferenceModel.findOneAndUpdate(queryText, updateText);
+ return res.status(200).send();
+ } catch (error) {
+ return res.status(400).send(error);
+ }
+ },
+
async fetchSingle(req, res) {
let slug = req.params.slug
@@ -203,196 +308,200 @@ const Jobs = {
let categories = ['full-time','part-time','contract'];
//Check for the type of the param being passed, a tech, a category or a custom URL
- if(techs.includes(slug)) {
- try {
- let tech = slug;
- let allStackJobs = [];
- let formalTech = tech.charAt(0).toUpperCase() + tech.slice(1);
-
- //Algo for deriving a stack job by checking if the desc includes the tech passed to the param
+ if (techs.includes(slug)) {
+ try {
+ let tech = slug;
+ let allStackJobs = [];
+ let formalTech = tech.charAt(0).toUpperCase() + tech.slice(1);
+
+ //Algo for deriving a stack job by checking if the desc includes the tech passed to the param
+ for (let i = 0; i < main.length; i++){
+ if (main[i].description.toLowerCase().includes(tech)) {
+ allStackJobs.push(main[i]);
+ continue;
+ }
+ };
+ //For jobs without an image
+ allStackJobs.slice().map(function (job) {
+ job.company_logo = (!job.company_logo) ? "/images/no_job_image.jpg" : job.company_logo;
+ return job;
+ });
+ return res.status(200).render('jobStack', {
+ name: formalTech,
+ status: 'success',
+ TotalJobs: Object.keys(allStackJobs).length,
+ data: allStackJobs,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user
+ });
+
+ } catch (error) {
+ return res.status(400).send(error);
+ }
+ }
+ else if (categories.includes(slug)) {
+ try {
+ //Refine the slugs for effective searching, remove the hyphens and capitalize each word
+ if (slug.includes('-')) {
+ let newSlug = slug.charAt(0).toUpperCase() + slug.slice(1);
+ let oldSlug = newSlug.split('-');
+ oldSlug[1] = oldSlug[1].charAt(0).toUpperCase() + oldSlug[1].slice(1);
+ var formalSlug = oldSlug.join(' ');
+ }
+ else {
+ var formalSlug = slug.charAt(0).toUpperCase() + slug.slice(1);
+ }
+
+ //Now Check if the query string has values
+ if (typeof req.query.tech == "undefined") {
+ let allCategoryJobs = [];
+
+
+ //Same algo as above...
for (let i = 0; i < main.length; i++){
- if (main[i].description.toLowerCase().includes(tech)) {
- allStackJobs.push(main[i]);
+ if (main[i].type == formalSlug || main[i].description.toLowerCase().includes(slug) ) {
+ allCategoryJobs.push(main[i]);
continue;
}
};
- //For jobs without an image
- allStackJobs.slice().map(function (job) {
+
+ //Jobs with no images
+ allCategoryJobs.slice().map(function (job) {
job.company_logo = (!job.company_logo) ? "/images/no_job_image.jpg" : job.company_logo;
return job;
});
- return res.status(200).render('jobStack', {
- name: formalTech,
+ return res.status(200).render('jobCategory', {
+ name: formalSlug,
status: 'success',
- TotalJobs: Object.keys(allStackJobs).length,
- data: allStackJobs
+ TotalJobs: Object.keys(allCategoryJobs).length,
+ data: allCategoryJobs,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user
});
-
- } catch (error) {
- return res.status(400).send(error);
- }
- }
- else if(categories.includes(slug)) {
- try {
- //Refine the slugs for effective searching, remove the hyphens and capitalize each word
- if (slug.includes('-')) {
- let newSlug = slug.charAt(0).toUpperCase() + slug.slice(1);
- let oldSlug = newSlug.split('-');
- oldSlug[1] = oldSlug[1].charAt(0).toUpperCase() + oldSlug[1].slice(1);
- var formalSlug = oldSlug.join(' ');
- }
- else {
- var formalSlug = slug.charAt(0).toUpperCase() + slug.slice(1);
- }
-
- //Now Check if the query string has values
- if (typeof req.query.tech == "undefined") {
- let allCategoryJobs = [];
-
-
- //Same algo as above...
+ }
+ else {
+ //If it does not have values, grab the values
+ let query = req.query.tech;
+ let selectedTech = query.split('|');
+
+ let selectedJobs = [];
+ for (let j = 0; j < selectedTech.length; j++) {
+ //Perform search with reference to relative parameters and add additional params where necessary
+ switch (selectedTech[j]) {
+ case 'react':
+ selectedTech.push('reactjs','react.js');
+ break;
+ case 'node':
+ selectedTech.push('nodejs','node.js');
+ break;
+ case 'java':
+ selectedTech[j] = ' java ';
+ break;
+ case 'ios':
+ selectedTech[j] = ' ios ';
+ break;
+ case 'cplusplus':
+ selectedTech[j] = 'c++';
+ break;
+ case 'asp':
+ selectedTech[j] = ' asp ';
+ selectedTech.push('asp.net')
+ break;
+ default:
+ break;
+ }
+ //Search for jobs and add them to the selected jobs array
for (let i = 0; i < main.length; i++){
- if (main[i].type == formalSlug || main[i].description.toLowerCase().includes(slug) ) {
- allCategoryJobs.push(main[i]);
+ if (main[i].type == formalSlug && main[i].description.toLowerCase().includes(selectedTech[j]) && selectedJobs.includes(main[i]) == false ) {
+ selectedJobs.push(main[i]);
continue;
}
};
-
- //Jobs with no images
- allCategoryJobs.slice().map(function (job) {
- job.company_logo = (!job.company_logo) ? "/images/no_job_image.jpg" : job.company_logo;
- return job;
- });
- return res.status(200).render('jobCategory', {
- name: formalSlug,
- status: 'success',
- TotalJobs: Object.keys(allCategoryJobs).length,
- data: allCategoryJobs
- });
- }
- else {
- //If it does not have values, grab the values
- let query = req.query.tech;
- let selectedTech = query.split('|');
-
- let selectedJobs = [];
- for (let j = 0; j\`\~\{\}\?\/\\\"\'\|\@\%\&\*]/g;
- let custom_url = url.toLowerCase().replace(regex, '-');
- job.custom_url = custom_url;
- return job;
+ };
+
+ let common_tech = ["python", "es6", "ruby", "c#", "java ", " C ", "c++", "php", "javascript", "css", "html", "swift", "git", "azure", "docker", "sql", "asp.net", ".net", "asp", "rest", "react", "ios", "android", "vagrant", "trello", " R ", "Linux", "Angular", "Node"];
+
+ let key_tech = search_common(single_job.description.toLowerCase(), common_tech);
+
+ let sortquery = key_tech.trim().split(", ");
+
+ for (let i = 0; i < sortquery.length; i++){
+ main.sort(function (a, b) {
+ var A = a.description, B = b.description;
+ if (A.includes(sortquery[i])) {
+ return 1;
+ } else if (B.includes(sortquery[i])) {
+ return -1;
}
- }).slice(0, 3);
-
- let summary = single_job.description.slice(0, single_job.description.indexOf("", 100));
-
- single_job.description = single_job.description.slice(summary.length);
-
- const stripeSession = await session;
-
- // some jobs have no image
- single_job.company_logo = (!single_job.company_logo) ? "/images/no_job_image.jpg" : single_job.company_logo;
-
- return res.status(200).render('singleJob', {
- content: single_job,
- summary: summary,
- keytech: key_tech + "...",
- title: single_job.title,
- similar_jobs: sub_data,
- sessionId: stripeSession.id
- })
- }
- catch (error)
- {
- return res.status(400).send(error);
+ });
}
+
+ let sub_data = main.filter(function (job) {
+ if (job.id !== single_job.id) {
+ job.company_logo = (!job.company_logo) ? "/images/no_job_image.jpg" : job.company_logo;
+ let url = job.title + ' ' + job.company;
+ let regex = /[\.\ \]\[\(\)\!\,\<\>\`\~\{\}\?\/\\\"\'\|\@\%\&\*]/g;
+ let custom_url = url.toLowerCase().replace(regex, '-');
+ job.custom_url = custom_url;
+ return job;
+ }
+ }).slice(0, 3);
+
+ let summary = single_job.description.slice(0, single_job.description.indexOf("", 100));
+
+ single_job.description = single_job.description.slice(summary.length);
+
+ const stripeSession = await session;
+
+ // some jobs have no image
+ single_job.company_logo = (!single_job.company_logo) ? "/images/no_job_image.jpg" : single_job.company_logo;
+
+ return res.status(200).render('singleJob', {
+ content: single_job,
+ summary: summary,
+ keytech: key_tech + "...",
+ title: single_job.title,
+ similar_jobs: sub_data,
+ sessionId: stripeSession.id,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user
+ })
+ }
+ catch (error)
+ {
+ return res.status(400).send(error);
}
+ }
+
-
},
async get_api_jobs(req, res) {
@@ -423,6 +532,7 @@ const Jobs = {
// main shii we're delivering, after slicing of course
content: main.slice(start_offset, end_offset),
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user,
// Next and previous buttons should not always show
buttons: {
previous: (page === 1) ? false : page - 1,
@@ -431,7 +541,7 @@ const Jobs = {
// we all need helpers. Baba God hear me out
- helpers:
+ helpers:
{
// this helps with displaying the page links, I guess
populate_links: function () {
@@ -471,7 +581,7 @@ const Jobs = {
};
try {
let createdJob = await db.create(queryText);
- // sendMailForRemoteJob(createdJob);
+ // sendMailForRemoteJob(createdJob);
return res.status(201).redirect("/admin/managejobs");
} catch (error) {
return res.status(400).send(error);
@@ -492,6 +602,7 @@ const Jobs = {
usersCount,
agentsCount,
paymentsCount,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user,
helpers: {
inc: function (index) {
index++;
@@ -529,7 +640,8 @@ const Jobs = {
return res.status(200).render("singleFeaturedJob", {
content: foundJob,
- sessionId: stripeSession.id
+ sessionId: stripeSession.id,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user
});
} catch (error) {
return res.status(400).send(error);
@@ -543,6 +655,7 @@ const Jobs = {
let foundFeaturedJobs = await db.find(queryText);
return res.status(200).render("manage_featured_jobs",{
content: foundFeaturedJobs,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user,
helpers: {
inc: function (index) {
index++;
@@ -554,7 +667,7 @@ const Jobs = {
}
}
-
+
});
} catch (error) {
return res.status(400).send(error);
@@ -662,7 +775,7 @@ const Jobs = {
let main = JSON.parse(JSON.stringify(remote_jobs));
let allFullTimeJobs = [];
- for (let i = 0; i < main.length; i++){
+ for (let i = 0; i < main.length; i++) {
if (main[i].type == "Full Time" || main[i].description.toLowerCase().includes("full time") ) {
allFullTimeJobs.push(main[i]);
continue;
@@ -678,7 +791,8 @@ const Jobs = {
name: "Full Time",
status: 'success',
TotalJobs: Object.keys(allFullTimeJobs).length,
- data: allFullTimeJobs
+ data: allFullTimeJobs,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user
});
} catch (error) {
@@ -692,7 +806,7 @@ const Jobs = {
let main = JSON.parse(JSON.stringify(remote_jobs));
let allPartTimeJobs = [];
- for (let i = 0; i < main.length; i++){
+ for (let i = 0; i < main.length; i++) {
if (main[i].description.toLowerCase().includes("part time") ) {
allPartTimeJobs.push(main[i]);
continue;
@@ -708,13 +822,14 @@ const Jobs = {
status: 'success',
message: "Sorry, there are no jobs available for this selected category",
TotalJobs: Object.keys(allPartTimeJobs).length,
- data: allPartTimeJobs
- });
+ data: allPartTimeJobs,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user
+ });
} catch (error) {
return res.status(400).send(error);
}
- },
+ },
//Unused for now, Please do not touch
async fetchAllContractSearchJobs(req, res) {
@@ -737,7 +852,8 @@ const Jobs = {
name: "Contract",
status: 'success',
TotalJobs: Object.keys(allContractJobs).length,
- data: allContractJobs
+ data: allContractJobs,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user
});
} catch (error) {
@@ -747,7 +863,7 @@ const Jobs = {
//Unused for now, Please do not touch
async fetchAllCustomSearchJobs(req, res) {
- const { search } = req.params;
+ const { search } = req.params;
try {
let allCustom = await fetch(`https://jobs.github.com/positions.json?search=${search}&location=remote`)
let allCustomJobs = await allCustom.json();
@@ -763,6 +879,6 @@ const Jobs = {
},
};
-
+
module.exports = Jobs;
\ No newline at end of file
diff --git a/controllers/home.js b/controllers/home.js
index d74ab0f0..e673306e 100644
--- a/controllers/home.js
+++ b/controllers/home.js
@@ -1,12 +1,12 @@
class Home {
// Render homepage
static index(req, res, next) {
- res.render("index", { title: "DevAlert | Home" });
+ res.render("index", { title: "DevAlert | Home", user: (typeof req.session.user == 'undefined') ? null : req.session.user,});
}
// Render about us page
static aboutUs(req, res, next) {
- res.render("about", { title: "DevAlert | About Us" });
+ res.render("about", { title: "DevAlert | About Us", user: (typeof req.session.user == 'undefined') ? null : req.session.user,});
}
// Dashboard
@@ -17,22 +17,22 @@ class Home {
// Render manage agents page
static manageagents(req, res, next) {
- res.render("manage_agents", { title: "Manage Agents" });
+ res.render("manage_agents", { title: "Manage Agents", user: (typeof req.session.user == 'undefined') ? null : req.session.user,});
}
// Render manage subscribers page
static managesubscribers(req, res, next) {
- res.render("manage_subscribers", { title: "Manage Subscribers" });
+ res.render("manage_subscribers", { title: "Manage Subscribers", user: (typeof req.session.user == 'undefined') ? null : req.session.user, });
}
// Render Privacy policy page
static privacy(req, res, next) {
- res.render("privacy");
+ res.render("privacy", { user: (typeof req.session.user == 'undefined') ? null : req.session.user});
}
// Render manage payment page
static manage_payments(req, res, next) {
- res.render("manage_payments", { title: "Manage Payment" });
+ res.render("manage_payments", { title: "Manage Payment", user: (typeof req.session.user == 'undefined') ? null : req.session.user});
}
//User Pages
@@ -48,57 +48,58 @@ class Home {
//Render contact details page
static contactUs(req, res, next) {
- res.render("contact");
+ res.render("contact", { user: (typeof req.session.user == 'undefined') ? null : req.session.user });
}
//Render contact details page
static terms(req, res, next) {
- res.render("terms");
+ res.render("terms", { user: (typeof req.session.user == 'undefined') ? null : req.session.user });
}
//Render FAQs page
static faqs(req, res, next) {
- res.render("faqs");
+ res.render("faqs", { user: (typeof req.session.user == 'undefined') ? null : req.session.user});
}
//Render Admin page
static admin(req, res, next) {
- res.render("admin");
+ res.render("admin", { user: (typeof req.session.user == 'undefined') ? null : req.session.user});
}
//Render Job listing
static get_job_page(req, res, next) {
- res.render("jobPage", { title: "Job Listing" });
+ res.render("jobPage", { title: "Job Listing", user: (typeof req.session.user == 'undefined') ? null : req.session.user });
}
// Render job details page
static job_details(req, res, next) {
- res.render("job_details", { title: "Job Details" });
+ res.render("job_details", { title: "Job Details", user: (typeof req.session.user == 'undefined') ? null : req.session.user, });
}
// Render choose agent page
static chooseAgent(req, res, next) {
- res.render("choose_agent", { title: "Choose an Agent" });
+ res.render("choose_agent", { title: "Choose an Agent", user: (typeof req.session.user == 'undefined') ? null : req.session.user, });
}
static managejobs(req, res, next) {
- res.render("manage_jobs", { title: "Manage Jobs" });
+ res.render("manage_jobs", { title: "Manage Jobs", user: (typeof req.session.user == 'undefined') ? null : req.session.user, });
}
static get_summary(req, res, next) {
res.render("get-summary", {
title: "Payment Summary",
- reference: req.query.reference
+ reference: req.query.reference,
+ user: (typeof req.session.user == 'undefined') ? null : req.session.user,
});
}
static get_applicant(req, res, next) {
- res.render("applicant", { title: "Applicant Details" });
+ res.render("applicant", { title: "Applicant Details", user: (typeof req.session.user == 'undefined') ? null : req.session.user, });
}
static unsubscribe(req, res, next) {
const email = req.query.email || "nomail";
- res.render("unsubscribe", { title: "unsubscribe", email });
+ res.render("unsubscribe", { title: "unsubscribe", email, user: (typeof req.session.user == 'undefined') ? null : req.session.user, });
}
static unsubscribe_success(req, res, next) {
- res.render("unsubscribe_success", { title: "unsubscribe success" });
+ res.render("unsubscribe_success", { title: "unsubscribe success", user: (typeof req.session.user == 'undefined') ? null : req.session.user, });
}
static category(req, res, next) {
- res.render("jobCategory", { title: "Full time" });
+ res.render("jobCategory", { title: "Full time", user: (typeof req.session.user == 'undefined') ? null : req.session.user, });
}
}
diff --git a/email-templates/contact.hbs b/email-templates/contact.hbs
index 44dc53e4..9c0ba6ed 100644
--- a/email-templates/contact.hbs
+++ b/email-templates/contact.hbs
@@ -1,5 +1,5 @@
-
+
title
diff --git a/email-templates/remote_job.hbs b/email-templates/remote_job.hbs
index 0a2940d0..c8c9fa10 100644
--- a/email-templates/remote_job.hbs
+++ b/email-templates/remote_job.hbs
@@ -1,5 +1,5 @@
-
+
title
diff --git a/email-templates/welcome.hbs b/email-templates/welcome.hbs
index 5bec185d..841a1de0 100644
--- a/email-templates/welcome.hbs
+++ b/email-templates/welcome.hbs
@@ -1,5 +1,5 @@
-
+
title
diff --git a/models/login.js b/models/login.js
index d8f8705c..ebaab33d 100644
--- a/models/login.js
+++ b/models/login.js
@@ -2,7 +2,7 @@ const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const socialSchema = new Schema({
- facebook: {
+ account: {
_id: {
type: String
@@ -16,6 +16,9 @@ const socialSchema = new Schema({
email: {
type: String
},
+ type: {
+ type: String
+ }
}
diff --git a/models/preferences.js b/models/preferences.js
new file mode 100644
index 00000000..a92074b3
--- /dev/null
+++ b/models/preferences.js
@@ -0,0 +1,11 @@
+const mongoose = require('mongoose');
+const Schema = mongoose.Schema;
+
+const preferenceSchema = new Schema({
+ _id: String,
+ stacks: [String],
+ job_types: [String],
+ mail_frequency: String
+});
+
+module.exports = mongoose.model('Preferences', preferenceSchema);
\ No newline at end of file
diff --git a/package.json b/package.json
index 5b9da497..c8f27d5a 100644
--- a/package.json
+++ b/package.json
@@ -10,7 +10,7 @@
"nodemon": "~1.18.10"
},
"dependencies": {
- "body-parser": "~1.18.3",
+ "body-parser": "^1.18.3",
"connect-flash": "~0.1.1",
"connect-mongo": "~2.0.3",
"cookie-parser": "~1.4.3",
@@ -35,6 +35,7 @@
"node-paystack": "^1.0.3",
"node-schedule": "^1.3.2",
"nodemailer": "^6.1.0",
+ "octonode": "^0.9.5",
"passport": "^0.4.0",
"passport-facebook": "^3.0.0",
"passport-google": "^0.3.0",
diff --git a/public/images/arrow-down.svg b/public/images/arrow-down.svg
index 9b88af8f..d8123d4c 100644
--- a/public/images/arrow-down.svg
+++ b/public/images/arrow-down.svg
@@ -1,7 +1,7 @@
-
-