Commit 11be441a authored by Ali's avatar Ali

initial commit

parent c6362c87
Pipeline #758 failed with stages
.git
node_modules
# editorconfig.org
root = true
[*]
indent_size = 2
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
# Auto detect text files and perform LF normalization
* text=auto
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Typescript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
config/local.js
.idea/
FROM node:8-alpine
WORKDIR /usr/src/app
EXPOSE 3000
# Copies dependencies in seperate layers
COPY package.json yarn.lock /usr/src/app/
RUN NODE_ENV=development
RUN yarn install --frozen-lockfile
ADD . /usr/src/app
CMD yarn dev
MIT License
Copyright (c) 2019 Ali
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# ceit backend # CEIT94-Backend
const Config = require('config')
module.exports = {
prefix: '/api',
routes: [
'./controllers/posts',
'./controllers/qualifications',
'./controllers/polls',
'./controllers/users',
'./controllers/notifications',
'./controllers/payment',
'./controllers/interviews'
],
registrations: [
'@bakjs/mongo',
'@bakjs/audit',
'@bakjs/auth',
'@bakjs/policy'
],
mongo: Config.get('mongo'),
auth: Config.get('auth'),
minio: Config.get('minio'),
policy: Config.get('policy')
}
module.exports = {
auth: {
secret: 'AUTH_SECRET',
oauth: {
aut: {
url: 'AUTH_OAUTH_AUT_URL',
redirect_uri: ' AUTH_OAUTH_AUT_REDIRECT_URL',
client_id: 'AUTH_OAUTH_AUT_CLIENT_ID',
client_secret: 'AUTH_OAUTH_AUT_CLIENT_SECRET'
},
google: {
url: 'AUTH_OAUTH_GOOGLE_URL',
redirect_uri: ' AUTH_OAUTH_GOOGLE_REDIRECT_URL',
client_id: 'AUTH_OAUTH_GOOGLE_CLIENT_ID',
client_secret: 'AUTH_OAUTH_GOOGLE_CLIENT_SECRET'
}
},
},
mongo: {
connections: {
default: {uri: 'mongodb://localhost:27017/ceit'}
}
},
haho: {
url: 'MQTT_HOST'
},
minio: {
endPoint: 'MINIO_ENDPOINT',
port: 'MINIO_PORT',
accessKey: 'MINIO_ACCESSKEY',
secretKey: 'MINIO_SECRETKEY',
public_url: 'MINIO_PUBLICURL'
},
log: {
sentry: {
dsn: 'SENTRY_DSN'
}
},
zarinpal: {
merchant_id: 'ZARINPAL_ID',
base_url: 'ZARINPAL_BASEURL'
}
}
module.exports = {
/**
* Configure mongodb
*/
mongo: {
connections: {
default: {uri: 'mongodb://localhost:27017/ceit'}
}
},
auth: {
secret: 'AUTH_SECRET',
oauth: {
aut: {
url: 'AUTH_OAUTH_AUT_URL',
redirect_uri: 'AUTH_OAUTH_AUT_REDIRECT_URL',
client_id: 'AUTH_OAUTH_AUT_CLIENT_ID',
client_secret: 'AUTH_OAUTH_AUT_CLIENT_SECRET'
},
google: {
url: 'AUTH_OAUTH_GOOGLE_URL',
redirect_uri: ' AUTH_OAUTH_GOOGLE_REDIRECT_URL',
client_id: 'AUTH_OAUTH_GOOGLE_CLIENT_ID',
client_secret: 'AUTH_OAUTH_GOOGLE_CLIENT_SECRET'
}
}
},
minio: {
endPoint: 'MINIO_ENDPOINT',
port: 'MINIO_PORT',
accessKey: 'MINIO_ACCESSKEY',
secretKey: 'MINIO_SECRETKEY',
public_url: 'MINIO_PUBLICURL'
},
zarinpal: {
merchant_id: 'ZARINPAL_ID',
},
log: {
sentry: {
dsn: 'SENTRY_DSN'
}
},
zarinpal: {
merchant_id: 'ZARINPAL_ID',
base_url: 'ZARINPAL_BASEURL'
},
//log: {
// sentry: {
// dsn: null
// },
// audit: {}
//},
policy: {
policies:''
}
}
const { Controller } = require('bak')
const { Interview } = require('../models')
const { Question } = require('../models')
const { User } = require('../models')
const Boom = require('boom')
class InterviewsController extends Controller {
init() {
this.post('/questions', this.createQuestion)
this.get('/questions', this.getQuestions, {
auth: {mode: 'try'}
})
this.post('/interviews/{question}/submit', this.submitInterviews)
this.get('/interviews', this.getInterviews)
this.post('/interviews', this.updateInBulk)
}
async submitInterviews (request, h) {
let answer = request.payload.answer
try {
let found = false
let user = await User.findById(request.user._id).populate('interviews')
let question = await Question.findById(request.params.question)
if (question.approved) {
for (let interview in user.toObject().interviews) {
if (user.interviews[interview].question.equals(question._id)) {
interview = await Interview.findById(user.interviews[interview]._id)
interview.answer = answer
await interview.save()
found = true
break
}
}
if (!found) {
let interview = new Interview({
question: question._id,
answer: answer
})
await interview.save()
user.interviews.push(interview)
}
}
await user.save()
return { saved: true }
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async getQuestions (request, h) {
try {
let questions = await Question.find({approved: true})
return { questions }
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async getInterviews(request, h) {
try {
let user = await User.findById(request.user._id).populate('interviews')
user = user.toObject()
for (let interview in user.interviews) {
user.interviews[interview].question = await Question.findById(user.interviews[interview].question)
}
return user
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async updateInBulk(request, h) {
let user = await User.findById(request.user._id).populate('interviews')
try {
let found = false
let interviews = request.payload.interviews
for (let interview in interviews) {
if (interviews[interview]._id) {
let interviewInDB = await Interview.findById(interviews[interview]._id)
interviewInDB.answer = interviews[interview].answer
await interviewInDB.save()
} else {
let question = await Question.findById(interviews[interview].question._id)
if (question.approved) {
for (let userInterview in user.toObject().interviews) {
if (user.interviews[userInterview].question.equals(question._id)) {
let interviewInDB = await Interview.findById(user.interviews[userInterview]._id)
interviewInDB.answer = interviews[interview].answer
await interviewInDB.save()
found = true
break
}
}
if (!found) {
let interviewInDB = new Interview({
question: question._id,
answer: interviews[interview].answer
})
await interviewInDB.save()
user.interviews.push(interviewInDB)
}
}
}
}
await user.save()
return { saved: true }
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async createQuestion(request, h) {
try {
let question = request.payload.question
question = new Question({
approved: false,
text: question
})
await question.save()
return {question}
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
}
module.exports = InterviewsController
const { Controller } = require('bak')
const { Notification } = require('../models')
const Boom = require('boom')
class NotificationsController extends Controller {
init () {
this.get('/notifications', this.showAllNotifications)
// this.post('/notifications', this.createNotification)
// this.delete('/notifications/{notification}', this.deleteNotification)
}
async showAllNotifications (request, h) {
let notifications
try {
notifications = await Notification.find()
return { notifications }
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async createNotification (request, h) {
let notification
try {
notification = new Notification(request.payload)
await notification.save()
return notification
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async deleteNotification (request, h) {
let notification = request.params.notification
try {
notification = await Notification.findByIdAndRemove(notification)
return { deleted: true }
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
}
module.exports = NotificationsController
const {Controller} = require('bak')
const {User} = require('../models')
const Boom = require('boom')
const Config = require('config');
const ZarinpalCheckout = require('zarinpal-checkout');
const zarinpal = ZarinpalCheckout.create(Config.get('zarinpal.merchant_id'), false);
// const baseUrl = Config.get('zarinpal.base_url')
const baseUrl = 'https://ceit93.ir/'
class PaymentController extends Controller {
init() {
this.post('/payment/pay', this.pay)
this.post('/payment/add', this.add)
this.get('/payment/check/add', this.checkAdd)
this.get('/payment/check', this.check)
this.get('/payment/status', this.status)
}
async checkAdd(request, h) {
let params = request.query;
let user = await User.findById(request.user._id);
let transaction = {};
let transactionID = 0;
user.addFamily.forEach((e,i) => {
if (params.Authority === e.Authority) {
transaction = e;
transactionID = i;
}
});
if (transaction === {})
return Boom.badRequest('درخواست بدی فرستادی :دی');
else {
try {
if (!params.Authority)
return Boom.badRequest('درخواست بدی فرستادی :دی');
// check user send him/her self authority as query string
if (params.Status === 'OK') {
// if user payed the cost => no need to verify
if (transaction.status) {
return this.getUserRegister(user);
}
let verify = await zarinpal.PaymentVerification({
Amount: (transaction.newFamily - user.registration.family) * 30 * 1000, // In Tomans
Authority: params.Authority,
});
if (verify.status === 100) {
user.addFamily[transactionID].status = true;
console.log(user.addFamily[transactionID]);
user.registration.cost += (transaction.newFamily - user.registration.family) * 30;
user.registration.family = transaction.newFamily;
await user.save();
return this.getUserRegister(user)
}
}
else if (params.Status === 'NOK') {
let verify = await zarinpal.PaymentVerification({
Amount: (transaction.newFamily - user.registration.family) * 30 * 1000, // In Tomans
Authority: params.Authority,
});
if (verify.status === -21)
throw Boom.paymentRequired('هیچ نوع عملیاتی برای این تراکنش یافت نشد.:(')
else if (verify.status === 100)
return this.getUserRegister(user)
else
throw Boom.paymentRequired('با پشتیبانی تماس بگیرید. عارف حسینی کیا : 09024855528')
} else { // Bad Request
}
throw Boom.paymentRequired('لطفا از قسمت ثبت نام جشن هزینه خود را پرداخت کنید.')
} catch (e) {
return e;
}
}
}
/**
* Checks that user payed the cost or not
* @param request
* @param h
* @returns {Promise<*>}
*/
async check(request, h) {
let params = request.query;
let user = await User.findById(request.user._id);
try {
if (!params.Authority)
return Boom.badRequest('درخواست بدی فرستادی :دی');
// check user send him/her self authority as query string
if (params.Status === 'OK') {
// checks loggedIn user payed him/her self cost
if (user.registration.Authority === params.Authority) {
// if user payed the cost => no need to verify
if (user.registration.status && this.isPayedCorrect(user.registration)) {
return this.getUserRegister(user);
}
let verify = await zarinpal.PaymentVerification({
Amount: user.registration.cost * 1000, // In Tomans
Authority: params.Authority,
});
if (verify.status === 100 && this.isPayedCorrect(user.registration)) {
user.registration.status = true;
await user.save();
return this.getUserRegister(user)
}
}
}
else if (params.Status === 'NOK') {
let verify = await zarinpal.PaymentVerification({
Amount: user.registration.cost * 1000, // In Tomans
Authority: params.Authority,
});
if (verify.status === -21)
throw Boom.paymentRequired('هیچ نوع عملیاتی برای این تراکنش یافت نشد.:(')
else if (verify.status === 100)
return this.getUserRegister(user)
else
throw Boom.paymentRequired('با پشتیبانی تماس بگیرید. عارف حسینی کیا : 09024855528')
} else { // Bad Request
}
throw Boom.paymentRequired('لطفا از قسمت ثبت نام جشن هزینه خود را پرداخت کنید.')
} catch (e) {
return e;
}
}
/**
* User requests to pay the cost and we return gateway url to him
* @param request
* @param h
* @returns {Promise<{gateway: {url: *}}>}
*/
async pay(request, h) {
let payload = request.payload;
// get user
let user = await User.findById(request.user._id)
try {
// first try to get gateway from zarinpal
let gateway = await zarinpal.PaymentRequest({
Amount: this.isPayedCorrect({
selfPayed: user.registration.selfPayed,
cost: payload.cost,
family: payload.family
}) ? payload.cost * 1000 : 0,
CallbackURL: `${baseUrl}/register/added`,
Description: 'پرداخت هزینه جشن فارغ التحصیلی 1393',
Email: payload.email,
Mobile: payload.phone
});
payload.Authority = gateway.authority;
let keys = Object.keys(payload);
keys.forEach((e) => {
user.registration[e] = payload[e]
});
await user.save();
return {
gateway: {
url: gateway.url
}
}
} catch (e) {
console.log(e);
}
}
/**
* User requests to edit his family and we return gateway url to him
* @param request
* @param h
* @returns {Promise<{gateway: {url: *}}>}
*/
async add(request, h) {
let newFamily = request.payload.newFamily;
// get user
let user = await User.findById(request.user._id)
if (user.registration.status) {
if (user.registration.family === newFamily)
return Boom.paymentRequired('نفراتی اضافه نشده اند.')
else {
try {
// first try to get gateway from zarinpal
let gateway = await zarinpal.PaymentRequest({
Amount: (newFamily - user.registration.family) * 30 * 1000,
CallbackURL: `${baseUrl}/register/added`,
Description: 'اضافه کردن مهمان جشن فارغ التحصیلی 1393',
Email: user.registration.email,
Mobile: user.registration.phone
});
user.addFamily.push({
Authority: gateway.authority,
newFamily: newFamily,
date: new Date(),
status: false
});
await user.save();
return {
gateway: {
url: gateway.url
}
}
} catch (e) {
console.log(e);
}
}
} else {
throw Boom.paymentRequired('ابتدا ثبت نام کنید.')
}
}
/**
* Return payment status of user.
* @param request
* @param h
* @returns {Promise<*>}
*/
async status(request, h) {
try {
let user = await User.findById(request.user._id);
if (user.registration.status)
return {
status: user.registration.status,
ticket: this.getUserRegister(user)
}
return {
status: user.registration.status,
selfPayed: user.registration.selfPayed,
}
} catch (e) {
}
}
/**
* Checks that registration cost is correct depend on selfPayed(user),family,cost(request)
* @param registration
* @returns {boolean}
*/
isPayedCorrect(registration) {
if (registration.selfPayed)
return registration.cost === (registration.family * 30) + 15;
else
return registration.cost === (registration.family) * 30 + 45;
}
/**
* Return object that should be in response when the user is registered successfully
* @param user
* @returns {{name, email: *|email|{type, required}|{type, index, sparse, unique}, phone: *|phone|{type, required}|string, family: *|family|{type, required}, cost: *|cost|{type, required}}}
*/
getUserRegister(user) {
return {
name: user.name,
email: user.registration.email,
phone: user.registration.phone,
family: user.registration.family,
cost: user.registration.cost
}
}
}
module.exports = PaymentController
const { Controller } = require('bak')
const { Vote } = require('../models')
const { User } = require('../models')
const { Qualification } = require('../models')
const { TopTarin } = require('../models')
const Boom = require('boom')
class PollsController extends Controller {
init (){
this.post('/poll/submit', this.submitPolls)
this.get('/polls', this.getSavedPollsByUser)
this.get('/polls/results', this.getAllVoteResults)
this.get('/polls/tarins', this.getTarins)
this.get('/polls/{username}', this.getTopTarinsByUser)
}
async submitPolls (request, h) {
try {
let user = await User.findById(request.user._id)
let votes = request.payload.votes
user.votes = votes
await user.save()
return user.votes
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async getAllVoteResults (request, h) {
if (request.user.toObject().is_admin) {
let totalResults = []
try {
let targetUsers = await User.find()
let i = 0
let users = await User.find()
for (let targetUser of targetUsers) {
let voteResults = []
for (let user of users) {
for (let vote of user.votes) {
if (vote.candidate) {
if (targetUser._id.equals(vote.candidate)) {
let voteResult = {}
let voter = user
voteResult.tarin = vote.qualification.title
voteResult.voter = voter.name
voteResults.push(voteResult)
}
}
}
}
let totalResult = {}
totalResult.name = targetUser.name
totalResult.votes = voteResults
totalResults.push(totalResult)
}
return totalResults
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
} else {
return Boom.unauthorized()
}
}
async getTarins (request, h) {
if (request.user.toObject().is_admin) {
let totalResults = []
try {
let targetUsers = await User.find()
let qualifications = await Qualification.find({approved: true}).lean()
let i = 0
let users = await User.find()
for (let user of users) {
for (let vote of user.votes) {
for (let qualification in qualifications) {
if (vote.candidate && qualifications[qualification]._id.equals(vote.qualification._id)) {
for (let targetUser of targetUsers) {
if (targetUser._id.equals(vote.candidate)) {
if (!qualifications[qualification]['result']) {
qualifications[qualification]['result'] = {}
}
if (qualifications[qualification]['result'][targetUser.name]) {
qualifications[qualification]['result'][targetUser.name]++
} else {
qualifications[qualification]['result'][targetUser.name] = 1
}
break
}
}
}
if (qualifications[qualification]['result']) {
let winners = [Object.keys(qualifications[qualification]['result'])[0]]
for (let key in qualifications[qualification]['result'])
if (qualifications[qualification]['result'][winners[0]] < qualifications[qualification]['result'][key]) {
winners = []
winners.push(key)
} else if (qualifications[qualification]['result'][winners[0]] == qualifications[qualification]['result'][key] && winners.indexOf(key)== -1) {
winners.push(key)
}
qualifications[qualification]['winners'] = winners
}
}
}
}
return qualifications
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
} else {
return Boom.unauthorized()
}
}
async getTopTarinsByUser(request, h){
let username = request.params.username
let results = []
try{
let targetUser = await User.findOne({username:username})
let users = await User.find()
let voteResults = []
for (let user of users) {
for (let vote of user.votes) {
if (vote.candidate) {
if (targetUser._id.equals(vote.candidate)) {
voteResults.push(vote.qualification._id)
}
}
}
}
let voteCounts = []
let count
for(let userVote of voteResults) {
count = voteResults.filter(
function (id) {
return id === userVote
}
).length
let voteCount = {}
voteCount.id = userVote
voteCount.count = count
if (
(voteCounts.filter(
function (e) {
return e.id === userVote
}
).length) === 0
) {
voteCounts.push(voteCount)
}
}
let sorted = voteCounts.sort(function IHaveAName(a, b) {
return b.count > a.count ? 1
: b.count < a.count ? -1
: 0;
});
for(let i=0; i<7; i++){
let result = {}
let qual = await Qualification.findById(sorted[i].id)
result.name = qual.title
result.count = sorted[i].count
results.push(result)
}
return results
} catch (e){
console.log(e)
throw Boom.badRequest()
}
}
async getSavedPollsByUser (request, h) {
let user
try {
user = await User.findById(request.user._id)
let votes = user.votes.toObject()
if (!user.locked){
user.locked = true
await user.save()
let quals = await Qualification.find({approved: true})
// Find the new approved qualification
for(let i in quals){
let qual = quals[i]
let found = false
for (let j in votes){
let vote = votes[j]
if(qual._id.equals(vote.qualification._id))
found = true
}
if (!found){
let vote = new Vote()
vote.qualification = qual
vote.candidate = null
votes.push(vote)
}
}
user.locked = false
user.votes = votes
await user.save()
return user.votes
} else {
throw Boom.badRequest()
}
} catch (e) {
console.log(e)
user.locked = false
await user.save()
throw Boom.badRequest()
}
}
async putResultsInCollection(request , h){
let forbiddenTarins = [
'5b13d5675f6c8430dc25a0fb',
'5b178dcdcc274c001a094c5f',
'5b1932930f1bff001a201d74',
'5b1e34b8ed40a9001aa33793',
'5b13d4f55f6c8430dc25a0ee',
'5b13d4045f6c8430dc25a0d7',
'5b13d1d25f6c8430dc25a0ab',
'5b13d25a5f6c8430dc25a0b9',
'5b13d2bf5f6c8430dc25a0c5',
];
let allUsers = await User.find()
let partialUsers = allUsers.slice(250,267)
for(let targetUser of partialUsers) {
let results = []
let users = await User.find()
let voteResults = []
for (let user of users) {
for (let vote of user.votes) {
if (vote.candidate) {
if (targetUser._id.equals(vote.candidate)) {
if (!forbiddenTarins.includes(vote.qualification._id)) {
voteResults.push(vote.qualification._id)
}
}
}
}
}
let voteCounts = []
let count
for (let userVote of voteResults) {
count = voteResults.filter(
function (id) {
return id === userVote
}
).length
let voteCount = {}
voteCount.id = userVote
voteCount.count = count
if (
(voteCounts.filter(
function (e) {
return e.id === userVote
}
).length) === 0
) {
voteCounts.push(voteCount)
}
}
let sorted = voteCounts.sort(function func(a, b) {
return b.count > a.count ? 1
: b.count < a.count ? -1
: 0;
});
for (let i = 0; i < 5; i++) {
let result = {}
if (sorted.length > i) {
let qual = await Qualification.findById(sorted[i].id)
let underlined_title = qual.title.replace(new RegExp(' ', 'g'), "_")
result.name = underlined_title
results.push(result)
}
}
user.topTarins = results
let topTarin = new TopTarin();
topTarin.user = targetUser._id
topTarin.topTarins = results
await topTarin.save()
}
}
}
module.exports = PollsController
const { Controller } = require('bak')
const { Post, User } = require('../models')
const Boom = require('boom')
const { upload, url } = require('@bakjs/minio')
class PostsController extends Controller {
init () {
this.get('/posts', this.showAllPosts)
this.get('/posts/wall', this.showAllWall)
this.post('/posts/wall/{user}', this.createPostWall, {
payload: {
maxBytes: 1000 * 1000 * 5 // 5Mb
}
})
this.get('/posts/{post}', this.showPost)
this.post('/posts/{post}', this.updatePost, {
payload: {
maxBytes: 1000 * 1000 * 5 // 5Mb
}
})
this.post('/posts', this.createPost, {
payload: {
maxBytes: 1000 * 1000 * 5 // 5Mb
}
})
this.delete('/posts/{post}', this.deletePost)
this.get('/posts/owner/{postID}' , this.getPostOwner)
}
async showAllPosts (request, h) {
// request.authorize('is_93')
try {
let user = await User.findById(request.user._id).populate('posts')
let posts = []
for (let post of user.posts) {
if (post.user.equals(request.user._id)) {
posts.push(post)
}
}
return { posts }
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async showAllWall(request, h) {
// request.authorize('is_93')
try {
let user = await User.findById(request.user._id).populate('posts')
let posts = []
for (let post of user.posts) {
if (!post.user.equals(request.user._id)) {
posts.push(post)
}
}
return { posts }
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async showPost (request, h) {
let post = request.params.post
try {
post = await Post.findById(post)
if (post) {
return post
} else {
return Boom.notFound()
}
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async createPost (request, h) {
// request.authorize('is_93')
let post
let image = request.payload.image
delete request.payload.image
try {
post = new Post(request.payload)
post.user = request.user._id
post.approved = true
await post.save()
if (image instanceof Buffer) {
image = await upload('posts', post._id + '.jpg', image, 'image/jpeg')
image = url('posts', post._id + '.jpg', image, 'image/jpeg')
}
post.image = image
await post.save()
let user = await User.findById(request.user._id)
user.posts.push(post)
await user.save()
return post
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async createPostWall (request, h) {
let userWall = await User.findById(request.params.user)
// request.authorize('can_post_wall', userWall)
let post
let image = request.payload.image
delete request.payload.image
try {
post = new Post(request.payload)
if (image instanceof Buffer) {
image = await upload('posts', post._id + '.jpg', image, 'image/jpeg')
image = url('posts', post._id + '.jpg', image, 'image/jpeg')
}
post.user = request.user._id
post.approved = false
post.image = image
await post.save()
let user = await User.findById(request.params.user)
user.posts.push(post)
await user.save()
return post
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async updatePost (request, h) {
let post = request.params.post
let image = request.payload.image
try {
let approved = request.payload ? (request.payload.data ? request.payload.data.approved : null) : null
let toBeUpdatedPost = await Post.findById(post)
if (request.user._id.equals(toBeUpdatedPost.user)) {
if (request.payload.data) {
if (request.payload.data.approved)
delete request.payload.data.approved
toBeUpdatedPost.set(request.payload.data)
toBeUpdatedPost.approved = false
}
if (image instanceof Buffer) {
image = await upload('posts', toBeUpdatedPost._id + '.jpg', image, 'image/jpeg')
image = url('posts', toBeUpdatedPost._id + '.jpg', image, 'image/jpeg')
toBeUpdatedPost.image = image
toBeUpdatedPost.approved = false
} else if (image === '') {
toBeUpdatedPost.image = image
toBeUpdatedPost.approved = false
}
toBeUpdatedPost = await toBeUpdatedPost.save()
}
if (request.user.posts.indexOf(post) !== -1) {
toBeUpdatedPost.approved = approved
await toBeUpdatedPost.save()
}
return {toBeUpdatedPost}
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async deletePost (request, h) {
let post = request.params.post
try {
let toBeDeletedPost = await Post.findById(post)
if (request.user._id.equals(toBeDeletedPost.user)) {
let user = await User.findOne({posts: post})
for (let post in user.posts) {
if (user.posts[post].equals(toBeDeletedPost._id)) {
user.posts.splice(post, 1)
break
}
}
await user.save()
post = await Post.findByIdAndRemove(post)
return { deleted: true }
} else {
return Boom.unauthorized()
}
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async getPostOwner(request, h){
let postID = request.params.postID
try{
let user = await User.find({ 'posts' : {'_id': postID} })
if (user.length > 0)
return user[0]
else
throw Boom.badRequest()
}catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
}
module.exports = PostsController
const { Controller } = require('bak')
const { Qualification } = require('../models')
const { User } = require('../models')
const Boom = require('boom')
class QualificationsController extends Controller {
init() {
this.post('/qualification/create', this.createQualification)
this.get('/qualifications', this.showAllQualifications)
this.get('/qualifications/nonapproved', this.showPendingQualifications)
}
async showAllQualifications (request, h) {
let quals
let { limit, skip } = request.query || {}
try {
quals = Qualification.find({ approved: true })
quals.limit(parseInt(limit) || 200)
quals.skip(parseInt(skip) || 0)
quals = await quals
return { quals }
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async showPendingQualifications (request, h) {
let quals
let results = []
try {
quals = await Qualification.find({ approved: false})
for(let qual of quals){
let result = {}
result.tarin = qual.title
result.approved = qual.approved
let creator = await User.findById(qual.creator)
if(creator) {
result.creator = creator.name
}
results.push(result)
}
return { results }
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async createQualification (request, h) {
let subject = request.payload.subject
let user = request.user
try{
let qualifications = await Qualification.find()
let isNewTarin = true
for (let qual of qualifications) {
if (qual.title === subject) {
isNewTarin = false
}
}
if (isNewTarin) {
let newQualification = new Qualification()
newQualification.title = subject
newQualification.approved = false
newQualification.creator = user._id
console.log(user._id)
await newQualification.save()
request.audit('SUBMIT_QUALIFICATION', newQualification)
}
return qualifications
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
}
module.exports = QualificationsController
const { Controller } = require('bak')
const { upload, url } = require('@bakjs/minio')
const { User } = require('../models')
const { Question } = require('../models')
const { Qualification } = require('../models')
const { TopTarin } = require('../models')
const Boom = require('boom')
class UsersController extends Controller {
init() {
this.post('/profie', this.updateProfile)
this.get('/users/students', this.getAll93Students, {
auth: {mode: 'try'}
})
this.get('/users', this.getAllUsers)
this.get('/users/{username}', this.getByUsername, {
auth: {mode: 'try'}
})
}
async getAll93Students (request, h){
try{
let users = await User.find({ $or: [{ std_numbers: { $regex: /^9331[0-9]{3}$/ } }, { authorized: true }] })
.select('_id name username std_numbers avatar gender modified_name grad_photo')
return users
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async getByUsername (request, h) {
let user = await User.findOne({ username: request.params.username }).populate('posts').populate('interviews')
// request.authorize('can_request_wall', user)
user.votes = undefined
user = user.toObject()
let toBeDisplayedPosts = []
for(let index in user.interviews){
user.interviews[index].question = await Question.findById(user.interviews[index].question)
}
if (request.user && user._id.equals(request.user._id)) {
for (let post in user.posts) {
let author = await User.findById(user.posts[post].user).select('_id name username std_numbers avatar gender modified_name grad_photo')
user.posts[post].user = author.toObject()
toBeDisplayedPosts.push(user.posts[post])
}
} else {
for (let post in user.posts) {
if ((request.user && user.posts[post].user.equals(request.user._id)) || user.posts[post].approved) {
let author = await User.findById(user.posts[post].user).select('_id name username std_numbers avatar gender modified_name grad_photo')
user.posts[post].user = author.toObject()
toBeDisplayedPosts.push(user.posts[post])
}
}
}
user.posts = undefined
user.posts = toBeDisplayedPosts
let username = user.username
let targetUser = await User.findOne({username:username})
let topTarinsObject = await TopTarin.findOne({user: targetUser})
user.topTarins = topTarinsObject.topTarins
return {user}
}
async updateProfile(request, h) {
let user = request.user._id
let avatar = request.payload.avatar
delete request.payload.avatar
try {
user = await User.findById(user)
if (avatar instanceof Buffer) {
avatar = await upload('users', user._id + '.jpg', avatar, 'image/jpeg')
avatar = url('users', user._id + '.jpg', avatar, 'image/jpeg')
user.avatar = avatar
}
await user.save()
return {avatar}
} catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
async getAllUsers(request, h) {
let results = []
try {
let users = await User.find()
for(let user of users){
let student_numbers = user.toObject().std_numbers
results.push(student_numbers)
}
results.sort()
return results
}
catch (e) {
console.log(e)
throw Boom.badRequest()
}
}
}
module.exports = UsersController
import { builtinModules } from "module";
function is_93 (user) {
if (user.authorized)
return true
for (let std_number of std_numbers) {
if (std_number.match(/^9331[0-9]{3}$/)) {
return true
}
}
return false
}
function is_author (user, post) {
if (user._id.equals(post.user)) {
return true
}
return false
}
function has_post (user, post) {
if (user.posts.indexOf(post._id) != -1) {
return true
}
return false
}
function can_request_wall(user, userWall) {
return is_93(userWall)
}
function can_delete_post (user, post) {
}
function can_post_wall (user, userWall) {
return is_93(userWall)
}
function access_results (user) {
let std_numbers = user.toObject().std_numbers
for (let std_number of std_numbers) {
}
}
module.exports = {
can_post_wall,
is_93,
can_request_wall,
has_post
}
const Post = require('./post')
const User = require('./user')
const Qualification = require('./qualification')
const Vote = require('./vote')
const Notification = require('./notification')
const Question = require('./question')
const Interview = require('./interview')
const TopTarin = require('./topTarin')
module.exports = {
User,
Post,
Qualification,
Vote,
Notification,
Question,
Interview,
TopTarin
}
const { Model, Schema } = require('@bakjs/mongo')
class Interview extends Model {
static get $schema () {
return {
question: { type: Schema.Types.ObjectId, ref: 'Question'},
answer: String,
}
}
}
module.exports = Interview.$model
const { Model, Schema } = require('@bakjs/mongo')
class Notification extends Model {
static get $schema () {
return {
title: String,
message: String,
type: String,
timeout: Number,
approved: Boolean
}
}
}
module.exports = Notification.$model
const { Model, Schema } = require('@bakjs/mongo')
class Post extends Model {
static get $schema () {
return {
title: String,
body: String,
image: String,
date: String,
approved: Boolean,
user: {type:Schema.Types.ObjectId, ref: 'User', required: true}
}
}
}
module.exports = Post.$model
const { Model, Schema } = require('@bakjs/mongo')
class Qualification extends Model {
static get $schema () {
return {
title: String,
approved: Boolean,
creator: { type: Schema.Types.ObjectId, ref: 'User' }
}
}
}
module.exports = Qualification.$model
\ No newline at end of file
const { Model, Schema } = require('@bakjs/mongo')
class Question extends Model {
static get $schema () {
return {
text: String,
approved: Boolean,
}
}
}
module.exports = Question.$model
const { Model, Schema } = require('@bakjs/mongo')
class TopTarin extends Model {
static get $schema () {
return {
user: {type:Schema.Types.ObjectId, ref: 'User', required: true},
topTarins: []
}
}
}
module.exports = TopTarin.$model
const {Model} = require('@bakjs/mongo')
const Auth = require('@bakjs/auth')
const {Schema} = require('@bakjs/mongo')
const registerSchema = new Schema({
selfPayed: {type: Boolean},
family: {type: Number},
cost: {type: Number},
Authority: {type: String},
phone: {type: String},
email: {type: String},
status: {type: Boolean}
})
class User extends Auth.User {
static get $visible() {
return ['_id', 'name', 'email', 'username', 'posts', 'votes', 'std_numbers','avatar', 'gender', 'authorized', 'interviews', 'is_admin', 'modified_name','addFamily', 'grad_photo']
}
static get $schema() {
return Object.assign({}, Auth.User.$schema, {
posts: [{type: Schema.Types.ObjectId, ref: 'Post'}],
avatar: String,
votes: [],
topTarins: [],
registration: registerSchema,
modified_name: String,
interviews: [{type: Schema.Types.ObjectId, ref: 'Interview'}],
locked: Boolean,
gender: String,
authorized: Boolean,
modified: String,
addFamily: [],
})
}
}
module.exports = User.$model
const { Model, Schema } = require('@bakjs/mongo')
class Vote extends Model {
static get $schema () {
return {
candidate: { type: Schema.Types.ObjectId, ref: 'User'},
qualification: Object
}
}
}
module.exports = Vote.$model
{
"name": "graduation-api",
"version": "1.0.0",
"private": true,
"description": "Graduation API",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon --exec yarn start",
"start": "bak start"
},
"repository": {
"type": "git",
"url": "git+https://github.com/ceit93/graduation-api.git"
},
"author": "Iman Tabrizian <tabrizian@outlook.com>",
"bugs": {
"url": "https://github.com/ceit93/graduation-api/issues"
},
"homepage": "https://github.com/ceit93/graduation-api#readme",
"dependencies": {
"@bakjs/audit": "*",
"@bakjs/auth": "^4.0.1",
"@bakjs/minio": "*",
"@bakjs/mongo": "^4.5.4",
"@bakjs/policy": "^3.0.1",
"bak": "^5.0.1",
"boom": "^7.3.0",
"config": "^3.1.0",
"zarinpal-checkout": "*"
},
"devDependencies": {
"nodemon": "*"
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment