This is the back-end for a Rental Property Web App using Node.js, Express, Mongoose and some other packages.
For development, you will need you will Node.js, NPM and all the packages in package.json to be installed.
A 'superadmin' type user is seeded from a .env file like so:
'SA_EMAIL=[email protected]'
The GET '/seedSuperAdmin' endpoint will provide a randomly generated password for this user when first run.
To install all the required packages, run the command below in the terminal after installing Node.js and NPM.
$ npm install
If the OS is linux, you must install redis-server on your system first. Please see https://tecadmin.net/install-redis-ubuntu/ for installing redis-server on your system.
To start the server run the command below in the terminal.
If Linux:
$ npm start
If Windows:
$ npm run start-win
Install an API Development Environment like Postman to make API requests. You need to set Header of content type 'application/json' and use JSON to pass in the values/fields to make a request.
POST '/createIssue'
form-fields:
{
'raisedBy': {
'userId': ObjectId(),
'userType': {
'type': 'String',
'enum': ['Landlord', 'Tenant']
},
'userName': 'String'
},
'submittedTo': {
'userId': ObjectId(),
'userName': 'String'
},
'acceptedBy':{
'userId': ObjectId(),
'userName': 'String'
},
'workStatus': {
'type': 'String',
'enum': ['Raised', 'Booked', 'Done']
},
'propertyDetail':{
ObjectId()
},
'landLord':{
'userId': ObjectId(),
'userName': 'String'
},
'priority':{
'type': 'String',
'enum':['Low','Medium','High']
},
'status': {
'type': 'String',
'enum': ['Active', 'Deleted'],
'default': 'Active'
}
}
GET '/getIssue/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
PUT '/updateIssue/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
DELETE '/deleteIssue/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
GET '/getPropertyList'
This endpoint has also optional filters (propertyType,rentStatus,Country, State, City)
GET '/getPropertyList?propertyType=house&rentStatus=rent&Country=USA&State=NY&City=Utica'
query parameters:
{
'Country': String,
'State': String,
'City' : String,
'propertyType' : String,
'rentStatus' : String
}
POST '/createProperty'
form-fields:
{
status: {
type: String,
enum: ['Active', 'Deleted'],
default: 'Active'
},
propertyType: {
type: String,
enum: ['house', 'flat', 'maisonette', 'bungalow', 'room only', 'garage'],
default: 'house'
},
propertySubType: String,
propertyImageUrls:[{type:String}],
leaseType:String,
Country:String,
Region:String,
State: String,
City:String,
PostalCode: Number,
State: String,
HouseNumber: Number,
Address:String,
Position: {
Latitude: Number,
Longitude: Number,
},
viewRequested:Boolean,
rentStatus: {
type: String,
enum: ['for sale', 'rent'],
default: 'for sale'
},
availability: {
type: String,
enum: ['taken', 'let agreed', 'available'],
default: 'available'
},
condition: {
type: String,
enum: ['furnished', 'part-furnished', 'unfurnished'],
default: 'unfurnished'
},
cooling: String,
IsLet: Boolean,
Heating: String,
NumberOfRoom: Number,
EnSuite: Number,
duration: Date,
propertyPrice: Number,
propertyCurrency: Number,
propertyPhotos: Array,
propertVideos: Array,
sponsored: Boolean
}
GET '/getProperty/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
PUT '/updateProperty/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
DELETE '/deleteProperty/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
PUT '/toggleSponsorProperty/:id'
query parameter:
{
'_id': ObjectId()
}
POST '/createRating'
form-fields:
{
'userId': ObjectId(),
'propertyId': ObjectId(),
'userName': 'String',
'picture': 'String',
'rating': 'Number',
'userType':{
'type': 'String',
'enum':['Landlord','Tenant']
},
'status': {
'type': 'String',
'enum': ['Active', 'Deleted'],
'default': 'Active'
}
}
GET '/getAllRating/{replace with the property id}'
query parameter:
{
'_id': ObjectId()
}
GET '/getRating/{replace with id}
query parameter:
{
'_id': ObjectId()
}
PUT '/updateRating/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
DELETE '/deleteRating/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
POST '/createTemplate'
form-fields:
{
'templateDetail': 'String',
'status': {
'type': 'String',
'enum': ['Active', 'Deleted'],
'default': 'Active'
}
}
GET '/getTemplate/{replace with id}
query parameter:
{
'_id': ObjectId()
}
PUT '/updateTemplate/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
DELETE '/deletTemplate/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
GET '/seedSuperAdmin'
POST '/login'
form-fields:
{
'email': 'String',
'password': 'String'
}
POST '/logout'
POST '/createUser'
form-fields:
{
email: { type: String, unique: true },
password: String,
passwordResetToken: String,
passwordResetExpires: Date,
userType: {
type: String,
enum: ["Landlord", "Tenant", "Contractor", "Admin", "SuperAdmin"]
},
status: {
type: String,
enum: ["Active", "Deleted"],
default: "Active"
},
region: String, // Will update it
profile: {
name: String,
gender: String,
location: String,
picture: {
imageURL: String,
imageID: String
}
},
provider: {
type: String,
default: "local"
}
}
GET '/getUser/{replace with id}
query parameter:
{
'_id': ObjectId()
}
PUT '/updateUser/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
DELETE '/deleteUser/{replace with id}'
query parameter:
{
'_id': ObjectId()
}
POST '/adminLogin'
query parameter:
{
admin: process.env.USER,
password: process.env.PWD
}
GET '/adminLogout'
Admin create property is an endpoint that helps create accurate properties by checking the giving address and make sure of its accuracy.
The address format is: houseNumber, street, city, state postalcode, country
POST '/adminapi/property/&houseNumber={housenumber}&street={street}&city={city}&state={state}&postalCode={postalCode}&country={country}'
EXAMPLE:
'/adminapi/property/&houseNumber=132&street=Sea%20St&city=Castine&state=ME&postalCode=04421&country=USA'
DELETE '/deleteProperty/{replace with id}'
Login with facebook and create a user with data fetched from facebook. You can see detail in 'config/passport.js' about login and register.
You have to change 'facebook.clientID' and 'facebook.clientSecret' in 'config/development.js' to yours with below page. (https://developers.facebook.com)
GET '/auth/facebook'
form-fields:
{
'email': { 'type': 'String', 'unique': 'true' },
'profile': {
'name': 'String',
'gender': 'String',
'location': 'String',
'picture': {
'imageURL': 'String',
'imageID': 'String'
}
},
'provider': 'facebook'
}
Login with google and create a user with data fetched from google. You can see detail in 'config/passport.js' about login and register.
You have to change 'google.clientID' and 'google.clientSecret' in 'config/development.js' to yours with below page. (https://console.developers.google.com)
GET '/auth/google'
form-fields:
{
'email': { 'type': 'String', 'unique': 'true' },
'profile': {
'name': 'String',
'gender': 'String',
'location': 'String',
'picture': {
'imageURL': 'String',
'imageID': 'String'
}
},
'provider': 'google'
}
Login with linkedin and create a user with data fetched from linkedin. You can see detail in 'config/passport.js' about login and register.
You have to change 'linkedin.clientID' and 'linkedin.clientSecret' in 'config/development.js' to yours with below page. (https://www.linkedin.com/developers)
GET '/auth/linkedin'
form-fields:
{
'email': { 'type': 'String', 'unique': 'true' },
'profile': {
'name': 'String',
'gender': 'String',
'picture': {
'imageURL': 'String',
'imageID': 'String'
}
},
'provider': 'linkedin'
}
join chatting room api
Join chatting: '/message/chat/:userid/:roomid/:propertyId'
Admin Chatting: 'admin/message/'
if propertyId is 0, get rooms from rooms collection else if propertyId is not 0, create new room with propertyId and get rooms.
if roomid is 0, currentRoom is set to first room in rooms getting from rooms collection. if roomid is not 0, currentRoom is set to the room with roomid
join room: io('/chatroom')
In client side, when socket get connect signal, emit join signal
join room: io.connect('/join', roomid, username) // join the room with roomid and username
when server socket is receiving 'join', if user is admin, send all messages to client. if user is normal user, find message with roomid and username and send them to client.
In server side, when socket get join signal, emit updateUserList, updateMessageList signal
update message signal: io.on('/updateMessageList', messages)
In client side, when socket get updateMessageList signal, update message history with received datas.
update user signal: io.on('/updateUserList', messages)
In client side, when socket get User signal, update user list with received datas.
new message: io.on('/newMessage', username, roomid, message)
In server side, when get newMessage signal, insert message to messages collection and send it to peer and admin.