Commit 8b9daf03 authored by Julio Guerra's avatar Julio Guerra

3st commit

parent a7beb8cc
No preview for this file type
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# 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 (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://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
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
#Databases credentials
# server/config/config.json
#Oauth2 credentials
# routes/api/config/config.json
*.crt
*.key
FROM node:11.6
WORKDIR /home/lalauch/api-lala
COPY package.json yarn.lock ./
RUN yarn --network-timeout 1000000 --frozen-lockfile
COPY . .
EXPOSE 3000
CMD [ "yarn", "start" ]
\ No newline at end of file
var express = require("express");
var path = require("path");
var favicon = require("serve-favicon");
var logger = require("morgan");
var cookieParser = require("cookie-parser");
var bodyParser = require("body-parser");
var db = require("./server/models");
var crudOperations = require("./crud")(db);
var apiV1 = require("./routes/api/v1/")(crudOperations, db);
var index = require("./routes");
var app = express();
let env = process.env.NODE_ENV || "development";
if (env === "production" || env === "test") {
app.set("trust proxy", true); // trust first proxy
}
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "jade");
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger("dev"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
app.use("/api", index);
app.use("/api/v1", apiV1);
app.get("/", (req, res) => {
res.send("API Working!");
});
var apiOptions = {
context: "/api2",
logger: { file: "mochaTest.log", level: "debug" },
discover: { path: "discover", secure: true },
// proto: { path: 'proto', secure: true }
};
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error("Not Found");
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
// render the error page
res.status(err.status || 500);
res.render("error");
});
module.exports = app;
#!/usr/bin/env node
/**
* Module dependencies.
*/
var app = require("../app");
var http = require("http");
var https = require("https");
var fs = require("fs");
let server;
let key;
let cert;
let PORT = 8000;
try {
key = fs.readFileSync(
"/etc/letsencrypt/live/trac.uach.lalaproject.org/privkey.pem"
);
cert = fs.readFileSync(
"/etc/letsencrypt/live/trac.uach.lalaproject.org/fullchain.pem"
);
server = https.createServer({ key, cert }, app);
} catch (err) {
server = http.createServer(app);
}
server.listen(PORT, () => {
console.log(`API Started on port ${server.address().port} `);
});
server.on("error", onError);
function onError(error) {
if (error.syscall !== "listen") {
throw error;
}
var bind = typeof port === "string" ? "Pipe " + port : "Port " + port;
switch (error.code) {
case "EACCES":
console.error(bind + " requires elevated privileges");
process.exit(1);
break;
case "EADDRINUSE":
console.error(bind + " is already in use");
process.exit(1);
break;
default:
throw error;
}
}
const request = require('request-promise')
const btoa = require('btoa')
const ISSUER = '';
const TEST_CLIENT_ID = '';
const TEST_CLIENT_SECRET = '';
const DEFAULT_SCOPE = '';
const ENDPOINT = '';
const test = async () => {
const token = btoa(`${TEST_CLIENT_ID}:${TEST_CLIENT_SECRET}`)
try {
const { token_type, access_token } = await request({
uri: `${ISSUER}/v1/token`,
json: true,
method: 'POST',
headers: {
authorization: `Basic ${token}`,
},
form: {
grant_type: 'client_credentials',
scope: DEFAULT_SCOPE,
},
})
const response = await request({
uri: ENDPOINT,
json: true,
rejectUnauthorized: false,
headers: {
authorization: [token_type, access_token].join(' '),
},
})
} catch (error) {
console.log(`Error: ${error.message}`)
}
}
test()
var Sequelize = require("sequelize");
const Op = Sequelize.Op;
module.exports = db => {
return {
/**
* Summary. Get a Program with a specific Curriculum.
*
* Description. Get a Program with a specific Curriculum.
*
* @param {int} id The id of the Program.
* @param {int} year The year of the Curriculum.
*
* @return {Object} The response object.
*/
getProgram: async (id, year) => {
const data = await db.curriculum.findOne({
where: {
"$program.id$": id,
"$program.state$": "active",
year: year,
state: "active",
},
include: [{ model: db.program }],
});
return data;
},
/**
* Summary. Get an Array of ProgramTerms with their Courses from a specific Curriculum.
*
* Description. Get an Array of ProgramTerms with their Courses from a specific Curriculum.
*
* @param {int} curriculum_id The id of the Curriculum.
*
* @return {Object} The response object.
*/
getProgramTerms: async curriculum_id => {
const terms = await db.program_term.findAll({
order: [["position", "ASC"]],
where: {
curriculum_id: curriculum_id,
[Op.or]: [
{ "$program_courses.state$": "active" },
{ "$program_courses.state$": null },
],
position: {
[Op.ne]: 0,
},
},
include: [
{
model: db.program_course,
include: [
{
model: db.course,
where: {
state: "active",
},
include: [
{
model: db.statistic,
},
],
},
],
},
],
});
return terms;
},
/**
* Summary. Get a Student academic from a program.
*
* Description. Get a Student academic from a program.
*
* @param {string} studentId The id of the Student.
* @param {int} programId The id of the Program.
*
* @return {Object} The response object.
*/
getStudentsAcademics: async (studentId, programId) => {
const student = await db.student.findOne({
order: [
// If I want to order for attributes belonging in other tables
[db.student_curriculum, db.curriculum, "year", "DESC"],
],
where: {
id: studentId,
state: "active",
},
include: [
{
model: db.student_curriculum,
include: [
{
model: db.curriculum,
where: {
state: "active",
},
include: {
model: db.program,
where: {
id: programId,
state: "active",
},
},
},
],
},
{
model: db.student_dropout,
},
],
});
return student;
},
/**
* Summary. Get the history academic of a student from an specific Curriculum.
*
* Description. Get the history academic of a student from an specific Curriculum.
*
* @param {string} studentId The id of the Student.
* @param {int} curriculumId The id of the Curriculum.
* @param {int} cohortYear The cohort year of the student. This parameter for the statistics cohort
*
* @return {Object} The response object.
*/
getHistoryAcademicStudentByCurriculum: async (
curriculumId,
studentId,
cohortYear
) => {
//Cohort year for the statistics cohort
const historyAcademics = await db.history_academic_course.findAll({
order: [["year", "ASC"], ["semester", "ASC"]],
where: {
student_id: studentId,
},
include: [
{
model: db.statistic_student_term,
/*on:{
col1: Sequelize.where(Sequelize.col("history_academic_course.year"), "=", Sequelize.col("statistic_student_term.year")),
col2: Sequelize.where(Sequelize.col("history_academic_course.semester"), "=", Sequelize.col("statistic_student_term.semester")),
col3: Sequelize.where(Sequelize.col("statistic_student_term.student_id"), "=", studentId)
}*/
},
{
model: db.course,
where: {
curriculum_id: curriculumId,
state: "active",
},
include: [
{
model: db.statisticTerm,
on: {
col1: Sequelize.where(
Sequelize.col("course.code"),
"=",
Sequelize.col("course->statisticTerms.course_code")
),
col2: Sequelize.where(
Sequelize.col("history_academic_course.year"),
"=",
Sequelize.col("course->statisticTerms.year")
),
col3: Sequelize.where(
Sequelize.col("history_academic_course.semester"),
"=",
Sequelize.col("course->statisticTerms.semester")
),
},
},
{
model: db.statistic,
on: {
col1: Sequelize.where(
Sequelize.col("course.code"),
"=",
Sequelize.col("course->statistic.course_code")
),
},
},
],
},
],
});
return historyAcademics;
},
getCourseAcademics: async courseId => {
const statisticTerms = await db.statisticTerm.findAll({
order: [[db.term, "year", "DESC"], [db.term, "semester", "ASC"]],
where: {
course_code: courseId,
},
include: [
{
model: db.term,
},
],
});
return statisticTerms;
},
/**
* Summary. Get the las date when the data were loaded in the database.
*
* Description. Get the las date when the data were loaded in the database.
*
* @return {Object} The response object.
*/
getLoadingDate: async () => {
const loadingDate = await db.parameter.findAll({
order: [["loading_date", "DESC"]],
});
return loadingDate.length === 0 ? null : loadingDate[0].loading_date;
},
};
};
This diff is collapsed.
{
"name": "api",
"version": "1.0.0",
"private": true,
"scripts": {
"devStart": "nodemon ./bin/api_exec",
"docker-push": "docker build -t pabloszx/api-lala . && docker push pabloszx/api-lala",
"sequelizeAuto": "sequelize-auto -o './server/models' -d <database> -h <ip> -u <username> -p 5432 -x '<password>' -e postgres",
"sequelizeCreateMigration": "sequelize migration:generate --name $NAME",
"sequelizeMigrate": "sequelize db:migrate",
"sequelizeMigrateUndo": "sequelize db:migrate:undo",
"start": "cross-env NODE_ENV=development PORT=3000 node ./bin/api_exec",
"testRequest": "concurrently \"nodemon ./bin/api_exec\" \"node clientRequestExample.js\""
},
"dependencies": {
"@okta/jwt-verifier": "0.0.14",
"body-parser": "^1.18.3",
"btoa": "^1.2.1",
"connect-rest": "^3.0.26",
"cookie-parser": "~1.4.3",
"d3": "^5.7.0",
"debug": "~2.2.0",
"event-stream": "^4.0.1",
"express": "^4.16.4",
"express-validator": "^5.3.0",
"jade": "~1.11.0",
"morgan": "^1.9.1",
"pg": "^7.5.0",
"pg-hstore": "^2.3.2",
"request-promise": "^4.2.2",
"sequelize": "^5.0.0-beta.14",
"serve-favicon": "^2.5.0",
"wagner-core": "^0.2.0"
},
"devDependencies": {
"concurrently": "^4.0.1",
"cross-env": "^5.2.0",
"nodemon": "^1.18.4"
}
}
This diff is collapsed.
This diff is collapsed.
define({
"name": "LALA API",
"version": "0.1.0",
"description": "The LALA API REST documentation.",
"title": "LALA API",
"url": "https://localhost:3000/api/v1",
"sampleUrl": false,
"defaultVersion": "0.0.0",
"apidoc": "0.3.0",
"generator": {
"name": "apidoc",
"time": "2019-02-08T20:47:07.171Z",
"url": "http://apidocjs.com",
"version": "0.17.6"
}
});
{
"name": "LALA API",
"version": "0.1.0",
"description": "The LALA API REST documentation.",
"title": "LALA API",
"url": "https://localhost:3000/api/v1",
"sampleUrl": false,
"defaultVersion": "0.0.0",
"apidoc": "0.3.0",
"generator": {
"name": "apidoc",
"time": "2019-02-08T20:47:07.171Z",
"url": "http://apidocjs.com",
"version": "0.17.6"
}
}
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
define({
ca: {
'Allowed values:' : 'Valors permesos:',
'Compare all with predecessor': 'Comparar tot amb versió anterior',
'compare changes to:' : 'comparar canvis amb:',
'compared to' : 'comparat amb',
'Default value:' : 'Valor per defecte:',
'Description' : 'Descripció',
'Field' : 'Camp',
'General' : 'General',
'Generated with' : 'Generat amb',
'Name' : 'Nom',
'No response values.' : 'Sense valors en la resposta.',
'optional' : 'opcional',
'Parameter' : 'Paràmetre',
'Permission:' : 'Permisos:',
'Response' : 'Resposta',
'Send' : 'Enviar',
'Send a Sample Request' : 'Enviar una petició d\'exemple',
'show up to version:' : 'mostrar versió:',
'Size range:' : 'Tamany de rang:',
'Type' : 'Tipus',
'url' : 'url'
}
});
define({
de: {
'Allowed values:' : 'Erlaubte Werte:',
'Compare all with predecessor': 'Vergleiche alle mit ihren Vorgängern',
'compare changes to:' : 'vergleiche Änderungen mit:',
'compared to' : 'verglichen mit',
'Default value:' : 'Standardwert:',
'Description' : 'Beschreibung',
'Field' : 'Feld',
'General' : 'Allgemein',
'Generated with' : 'Erstellt mit',
'Name' : 'Name',
'No response values.' : 'Keine Rückgabewerte.',
'optional' : 'optional',
'Parameter' : 'Parameter',
'Permission:' : 'Berechtigung:',
'Response' : 'Antwort',
'Send' : 'Senden',
'Send a Sample Request' : 'Eine Beispielanfrage senden',
'show up to version:' : 'zeige bis zur Version:',
'Size range:' : 'Größenbereich:',
'Type' : 'Typ',
'url' : 'url'
}
});
define({
es: {
'Allowed values:' : 'Valores permitidos:',
'Compare all with predecessor': 'Comparar todo con versión anterior',
'compare changes to:' : 'comparar cambios con:',
'compared to' : 'comparado con',
'Default value:' : 'Valor por defecto:',
'Description' : 'Descripción',
'Field' : 'Campo',
'General' : 'General',
'Generated with' : 'Generado con',
'Name' : 'Nombre',
'No response values.' : 'Sin valores en la respuesta.',
'optional' : 'opcional',
'Parameter' : 'Parámetro',
'Permission:' : 'Permisos:',
'Response' : 'Respuesta',
'Send' : 'Enviar',
'Send a Sample Request' : 'Enviar una petición de ejemplo',
'show up to version:' : 'mostrar a versión:',
'Size range:' : 'Tamaño de rango:',
'Type' : 'Tipo',
'url' : 'url'
}
});