Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
A backend framework for solid web apps based on node.js
You want to build a solid web application but you don't want to use express and alot of packages you need to build a basic website, Grandjs is one framework includes all main functionalities you need to build amazin, solid and secured web application without needing for ton of packages and libraries.
1- you need to install node.js on your system 2- init a new project using npm, so then we will be able to install this framework
//require HTTP module
const http = require("http");
//require Grandjs framework
const Grandjs = require("Grand");
// set the configuration of the framework
Grandjs.setConfig({
//define the port
port: process.env.PORT || 3000,
// http is optional you can specify http or https, if you don't specify Grandjs automatically require HTTP module
http: http,
// if you specified https so you should ssl files in this object
httpsMode: {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
}
// define the static files container folder
staticFolder: "public",
//enable the session
session: true,
//set the encryption key, Grandjs uses encription key to cypher info
ENCRYPTION_KEY: "ncryptiontestforencryptionproces",
// set the max age of cookies when you set the session of logged in users
setCookie: {
expires: {
days: 20,
minutes: 30
}
},
//set it true to see the console info while development process
logger: true,
//set error page for global error pages
errorPage(req, res) {
res.end("error page");
}
});
// init Grandjs
Grandjs.initServer();
content
open the command prompt and navigate to the project folder and just say
npm install grandjs --save
to start with Grandjs just install it and call it in your file as the following
//require Grandjs framework
const Grandjs = require("Grand");
if you want to require HTTP or HTTPS module to pass it to Grand js you can, in all cases Grandjs behind the seen requires HTTP module as a default.
Now you need to call seConfig function to set some configuration for the project
Grandjs.setConfig({});
this function takes one parameter as an object
Example on all configuration
const http = require("http");
const Grandjs = require("Grand");
// define Grandjs configuration
Grandjs.setConfig({
//define the port of the server
port: 3000,
// http is optional you can specify http or https, if you don't specify Grandjs automatically require HTTP module
http: http,
// define the static files container folder
staticFolder: "public",
//enable the session
session: true,
//set the encryption key, Grandjs uses encription key to cypher info
ENCRYPTION_KEY: "ncryptiontestforencryptionproces",
// set the max age of cookies when you set the session of logged in users
setCookie: {
expires: {
days: 20,
minutes: 30
}
},
//set it true to see the console info while development process
logger: true,
//set error page for global error pages
errorPage(req, res) {
res.end("error page");
}
})
until now Grandjs doesn't work so you need to call "init function" to initialize the server
Grandjs.init();
to work with router class you need to extend it or instatiate it directly and every class implies a group of routes have a specific basename
class HomeRouter extends Grandjs.Router{
constructor(options) {
super(options);
}
}
As any extended class you should call the super inside the constructor and pass the options parameter
parameter | type |
---|---|
options | Object |
Now after defining the class you should define the get routers which related to this class Router class has a property called "getRouters" this is an array and you push inside it the routers you add within the class with the GET method
Example
class HomeRouter extends Grandjs.Router{
constructor(options) {
super(options);
this.getRouters.push()
}
}
you can add routers which related to this class as methods inside the class and every method you use it as a router it should return an object has the following properties
Property | type | description |
---|---|---|
url | string (required) | the url of the router |
method | string (required) | HTTP method get / post / patch / put / delete |
handler | function (required) | the function you want to run whem the request url matches the router url |
middleWares | array (optional) | if you want to run a function or more to check about something before running the final handler of the router |
//push the homePage method route into getRouters array
this.getRouters.push(this.homePage);
}
homePage() {
return {
//define the url of router
url: "/",
// define the method of the router
method: "GET",
handler: () => {
// handle the request and do the functionalities
}
}
}
}
<hr style="border:.5px solid black;height:0">
###Define post routers
**Example**
```javascript
class HomeRouter extends Grandjs.Router{
constructor(options) {
super(options);
//push the homePage method route into getRouters array
this.postRouters.push(this.homePagePost);
}
homePagePost() {
return {
//define the url of router
url: "/",
// define the method of the router
method: "POST",
handler: () => {
// handle the request and do the functionalities
}
}
}
}
###instantiate router class Example
class HomeRouter extends Grandjs.Router{
constructor(options) {
super(options);
//push the homePage method route into getRouters array
this.getRouters.push(this.homePage);
}
homePage() {
return {
//define the url of router
url: "/",
// define the method of the router
method: "GET",
handler: () => {
// handle the request and do the functionalities
}
}
}
}
// instantiate the class
const homeRoters = new HomeRouter({});
when you instantiate the class you should define the options parameter as an object includes two properties
property | type | descriptions |
---|---|---|
base | string (required) | implies the base url you want to add routers to it. so if you defined it as "/admin" all routers inside this class would be added to /admin |
staticFolder | string(optional) | the name of the folder you want to serve assets and statoc files from it. The default value of it is the global staticFolder that you specified in setConfig function |
Example
const homeRoters = new HomeRouter({
base: "/"
});
to handle the routers and check requests and responses you need to access on them, so these object are accessable using different ways
1- req & res objects are properties inside the class Example
class HomeRouter extends Grandjs.Router{
constructor(options) {
super(options);
//push the homePage method route into getRouters array
this.getRouters.push(this.homePage);
}
homePage() {
return {
//define the url of router
url: "/",
// define the method of the router
method: "GET",
handler: () => {
// handle the request and do the functionalities
//request object: this.req
// response object: this.res
//console the request object headers
console.log(this.req.headers);
this.res.end("hello home page");
}
}
}
}
2- request & response are accessable as parameters inside handler function Example
homePage() {
return {
url: "/",
method: "get",
handler: (req, res) => {
console.log(req.headers);
res.end("hello home page");
}
}
}
Example
const adminRoute = new Grandjs.Router({
baes: "/admin"
})
// add main route to admin base
adminRoute.addRoute({
url: "/",
method: "get",
handler: (req, res) => {
res.end("hello admin");
}
});
// add profile page route to admin base
homePage.addRoute({
url: "/profile",
method: "get",
handler: (req, res) => {
res.end("hello profile");
}
});
1- define it inside the class Example
class HomeRouter extends Grandjs.Router{
constructor(options) {
super(options);
}
homePage() {
return {
url: "/",
method: "get",
handler: () => {
this.res.end("hello home page);
}
}
}
aboutPage() {
return {
url: "/about",
method: "get",
handler: () => {
this.res.end("hello about page);
}
}
}
// customize error page
errorPage() {
this.res.end("error page")
}
}
2-Define error page from outside the class Example
const homeRouter = new Grandjs.Router({
baes: "/"
})
// add main route to admin base
homeRouter.addRoute({
url: "/",
method: "get",
handler: (req, res) => {
res.end("hello homepage");
}
});
// add profile page route to admin base
homeRouter.addRoute({
url: "/about",
method: "get",
handler: (req, res) => {
res.end("hello aboutpage");
}
});
homeRouter.errorPage = (req, res) => {
res.end("error page");
}
*not that if you didn't define error page for the router class it automatically call error page which you specified in setConfig function
####Request Object this is an object you can access on it inside the handler of the route and the object contains the all information about the request which is coming
Property | type | description |
---|---|---|
req.method | string | returns the method of the current request |
req.pathname | string | returns the requested url without query string |
req.path | string | returns the requested url with query string |
req.href | string | returns the requested url with query string |
req.url | object | returns object contains the parsed url |
req.query | object | contains the query & search in the url(it parsed as key and value) |
req.params | object | returns the query parameters if it exists as key and value |
req.validation | object | returns an object contains some helper functions to valiate the email and string |
req.data | object | returns an object contains the posted data if the method is "post" |
req.headers | object | returns the headers of the comming request |
req.flash | object | this object enables you to set messages to send it to handlebars to show to the user |
returns an object contains the parameters of the router url and it's value if it exists if there is no params so it returns an empty object Example
const homePage = new Grandjs.Router({
baes: "/"
})
home.addRoute({
url: "/posts/:category",
method: "get",
handler: (req, res) => {
// user requested http://localhost:300/posts/tech?postId=2
console.log(req.params); //output {category:"tech"};
console.log(req.query) //output {postId: 2}
console.log(req.pathname) //output /posts/tech
console.log(req.path) //output /posts/tech?postId=2
console.log(req.href) //output /posts/tech?postId=2
console.log(req.method) //output "get"
console.log(req.url)
/* output
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?postId=2',
query: 'postId=2',
pathname: '/posts/tech',
path: '/posts/tech?postId=2',
href: '/posts/tech?postId=2' }
*/
}
});
Example
postAdminPage() {
return {
method: "post",
url: "/admin/addinfo",
handler: (req, res) => {
console.log(req.data) //output {} contains all submitted info
}
}
}
res.render
functionThis function you use it to render html content using handlebars template engine
res.render()
takes one parameter as an object, this object should contains the following properties:
property | type | description |
---|---|---|
container | string (required) | this property you specify the container folder which includes all handlebars files |
layout | string (required) | should be the path of the layout file |
body | string (optional) | should be the path of the body file |
partials | Array (optional) | every item inside this array should be a string refers to the path of the partial file that you want to append to the layout |
data | object (optional) | object contains the data you want to render inside the handlbars files |
Example |
homePageRouter() {
return {
url: "/",
method: "get",
handler: () => {
// render content using handlebars template engine
this.res.render({
container: "views",
layout: "/layouts/layout.hbs",
body: "/pages/home.hbs"
})
}
}
}
res.write
functionthis function is like the native api of node.js, it allows you to send strings to the client
res.write("hello world");
//end the response
res.end("");
res.end
functionthis function is like the native api of node.js, it allows you to send strings to the client
res.end("hello world");
res.sendFile
functionres.sendFile(path);
this function takes on parameter
parameter | type | description |
---|---|---|
path | String (required) | this parameter should specify the path of the file which you want to send |
this function uses promise to return a catch
function if the file isn't exist
Example
res.sendFile("/views/pages/home.html").catch((err) => {
console.log(err) //output no such file
})
####res.json
function
this function sends json data, it accepts one parameter this parameter should be an object and Grandjs stringify this object automatically
res.json({user: "tarek", email: "test@gmail.com", id: 1});
####res.redirect
function
This function is used to make redirect to another link
It accepts one parameter
parameter | type | description |
---|---|---|
url | String (required) | this parameter should specify url that you want to redirect to |
res.redirect("/anotherurl");
middlewares is a group of functions used to run something before executing the final handler
the middWares property should be an array includes the functions
Every middleware should has three parameters
parameter | type | description |
---|---|---|
req | object | implies the coming request object contains all information about the request |
res | object | represents the response object |
next | function | is a function you can execute it to continue to the final handler of the router |
Example |
//middle ware
function writeWithMiddleware(req, res, next) {
// has three parameters
/*
1- req: the request object
2- res: the response object
3- next: a function you execute it to continue to the handler
*/
res.write("from middleware");
next();
}
homePage() {
return {
url: "/home",
middleWares: [],
method: "get",
handler: (req, res) => {
res.end("hello home page");
// final output on the browser:
//from middleware
//hello home page
}
}
}
validation.checkEmail
functionThis function checks if the string is emain or not
this function takes two parameters
parameter | type | description |
---|---|---|
string (required) | this parameter is required and it should be string that you want to test it as email or not | |
cb | function (optional) | this is a callback function you can call it and includes one parameter either be true or false |
This function you can call it async with a callback function or sync without callback |
1- with callback function
Grandjs.helpers.validation.checkEmail("test@gmail.com", (email) => {
if(email) {
console.log(email) //output true if it email
} else {
console.log(email) // output false if itsn't email
}
});
2- without callback
let email = Grandjs.helpers.validation.checkEmail("test@gmail");
console.log(email) // returns true if it email, if not, returns false
This function checks if the given string is empty or not
it accepts two parameters:
parameter | type | description |
---|---|---|
string | string (required) | to test it is empty or not |
cb | function (optional) | this is a callback function you can call it and includes one parameter either be true or false |
This function you can call it async with a callback function or sync without callback |
1- with callback function
Grandjs.helpers.validation.notEmpty("", (notEmpty) => {
if(notEmpty) {
console.log(notEmpty) //output true if it is not empty
} else {
console.log(notEmpty) // output false if it is empty
}
});
2- without callback
let notEmpty = Grandjs.helpers.validation.notEmpty("");
console.log(email) // returns true if it isn't empty, if it is empty, returns false
This function checks if the given string contains numbers or not
it accepts three parameters:
parameter | type | description |
---|---|---|
string | string (required) | to test it contains numbers or not |
count | Number (required) | refers to the count of number you want to test the string contains. if you specify it for example 5 so the function checks if the given string contains five numbers |
cb | function (optional) | this is a callback function you can call it and includes one parameter either be true or false |
This function you can call it async with a callback function or sync without callback |
1- with callback function
Grandjs.helpers.validation.checkContainsNumber("Grandjs32test1", 3, (containsNumbers) => {
if(containsNumbers) {
console.log(containsNumbers) //output true if it contains number
} else {
console.log(containsNumbers) // output false if it doesn't contain three numbers
}
});
2- without callback
let containsNumbers =
Grandjs.helpers.validation.checkContainsNumber("Grandjs32test1", 3);
console.log(containsNumbers) // returns true if it contains 3 numbers, returns false if not
This function checks if the given parameter is a number or not you can use this function to authenticate phone number and stuf like that
it accepts two parameters:
parameter | type | description |
---|---|---|
val | any (required) | to test it is number or not |
cb | function (optional) | this is a callback function you can call it and includes one parameter either be true or false |
This function you can call it async with a callback function or sync without callback |
1- with callback function
let test = 1222;
Grandjs.helpers.validation.checkIsNumber(test, (number) => {
if(number) {
console.log(number) //output true if it is number
} else {
console.log(number) // output false if it isn't number
}
});
2- without callback
let test = 1222;
let number = Grandjs.helpers.validation.checkIsNumber(test);
console.log(number) // returns true if it is number, returns false if not
###Cryption
Grandjs gives you functionalities to crypt important info and cipher them and decrypt the
cryption functions are inside helpers inside grandjs library
This helper uses the ENCRYPTION_KEY
that you specify in setConfig
function.
####enCrypt
Grandjs.helpers.enCrypt(text);
This function takes one parameter which referes to the string you wanna encrypt or cipher it
parameter | type | description |
---|---|---|
text | string (required) | implies the text that you wanna cipher it |
This function rreturns the string after cipher it
// encrypt password
let encryptedPassword = Grandjs.helpers.enCrypt("passowrd");
This function rreturns the string after decipher it
// encrypt password
let decryptedPassword = Grandjs.helpers.deCrypt("passowrd");
###Session Grandjs represents to you a session module which you can use it in login processes and setting cookies for logged in users
Grandjs.setConfig
function as the following:Grandjs.setConfig({
// enable session module
session: true
})
2- now you need to set the max age of cookies for global sessions inside Grandjs.setConfig
function as the following:
Grandjs.setConfig({
//enable session
session: true
//set cookies for one month and 30 minutes, after that it would be removed
setCookie: {
expires: {
days: 30, // refers to one month
minutes: 30 //refers to 30 minutes
}
}
})
setCooki
is an object, you specify inside it an object called expires
this object has two properties
property | type | description |
---|---|---|
days | number (optional) | refers to the number of days that you want to set the cookie until it |
minutes | number | referes to the number of minutes that you want set the cookie until it |
Not that session is a global variable you can access on it from anywhere insde the project
Example on session inside handler function
postRouter () {
return {
url: "/user",
method: "post",
handler: () => {
let userdata = this.req.data;
// set it without custom cookie
session.set("userdata", userdata);
}
}
}
postRouter () {
return {
url: "/user",
method: "post",
handler: () => {
let userdata = this.req.data;
// set it without custom cookie
session.set("userdata", userdata, {
days: 1 // set the cookie for one day only
});
}
}
}
if the session is exist this function returns an object contains data that you have stored, and if no session with that name it will return an undefined
let info = session.getSession("userdata");
console.log(info) //output: object || undefined
session.breakSession
functionThis function breaks the session and stops it, so you use it when the user logs out
This function takes one parameter, that parameter is the name of the session that you want to break
// break the session
session.breakSession("userdata");
auth.login
functionThis function is used to login the user when he signs up or in.
session.set
function and auth.login
depends on itThis function takes three parameters:
parameter | type | description |
---|---|---|
loginName | string(required) | this parameter specified the name of the session for example if the session for login so you can set it as "userInfo" |
obj | object (required) | this is the info that you want to store in the session |
sessionOptions | object (optional) | represents specific cookie configuration for this session only |
// login the user
auth.login("userdata", {username: "tarek", email:"test@gmail.com"});
auth.checkAuth
functionThis function is used to check if the user is logged in or not
true
false
let logged = auth.checkAuth();
// output: true | false
// logout the user
auth.logout();
Flash is an object inside request
object, it allows you to set messages to send them to the handlebars to show allert messages or success or any message you want to show from backend to frontent
flash is accessable inside any router handler Example
// post router
router.addRoute({
url: "/login",
method: "post",
handler: () => {
// set error message
req.flash.errorMessage = "user not found"
}
})
// get router
router.addRoute({
url: "/login",
method: "get",
handler: () => {
this.res.render({
layouts: "./views/layouts/main.hbs",
body: "login.hbs",
data: {
errorMessage: this.req.flash.errorMessage
}
})
}
})
This project is licensed under the MIT License - see the LICENSE.md file for details
FAQs
A backend framework for solid web apps based on node.js
The npm package grandjs receives a total of 7 weekly downloads. As such, grandjs popularity was classified as not popular.
We found that grandjs demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.