Docs






 


1. Short Introduction



jsapp.cloud is the efficient solution for web applications based on CLOUD resources .
A collection of web services, tools, and web interfaces that creates the foundation for the fast development of modern, secure applications.

It offers an optimized backend and a lightweight client to build highly scalable web applications. It is secure and adheres to current standards for web development.

The backend is based on RESTful web services and implements all the required services for your web app, offering support to add new APIs as required by your system integration. The solution is tailored around Amazon AWS CLOUD services to provide one of the best environments for web apps. jsapp.cloud does not host your developed application by default; you will need to install the required resources in an Amazon AWS account, being in total control of your data privacy and services management.

Powered by NodeJS, the backend services covers:
- authorization, based on JWT
- CLOUD file access, based on S3 and data stream encryption
- database access API's for PostgreSQL
- application API's
- web server
- management interfaces

Proposed web client interfaces are based on HTML5, Bootstrap and VueJS.
The client application is hosted by the application web server and stored in encrypted CLOUD files by default.
Development is CLOUD based, the client interfaces is carefuly designed to offer on demmand resources loading
being used for very big web apps or small ones alike. The system is secured and can be used to develop applications for sensitive databases.

Users, groups and access right are managed based on high security standards.

You can develop fast web applications whether are small or large. Most of the backend and frontend is covered, all you need to do is to implement your app interfaces and business logic.

On demand resource loading:
Helps the application to start faster by loading only the initial files. All required routes and components will be loaded quickly upon request.
This model helps you :
- to build huge applications with practically unlimited number of routes
- continue development model, some parts of your live app can be under development or modified while the app is used in production

High scalability:
Horizontal scaling using small VPCs in parallel and load balancing provides a more reliable and cost-effective solution. Combined with AWS auto-scaling, it is a win.
The web server resources (HTML, CSS, JS, the web app ) are stored in the S3 file system, offering a single source similar to a custom CDN.
The cloud IDE assists with secure multi-developer access. The application development model does not require 'build' or server resource uploads to be updated.

Applications for the enterprise:
A virtually unlimited number of users; the application can scale for very large companies. Support for large applications and access rights based on user groups and app roles is available.
Built-in security against different attack types. Encrypted S3 file storage, encryption / decryption of data streams for high efficiency , and a DRIVE app module with folder-sharing options.
A lower development budget offers support for international applications and documentation. It respects EU GDPR legislation for personal data storage and access.


1.1. About



The presented solution development started in 2014 with some of the web services and continued over the years
with new parts or features required for differrent custom designed applications.

It is used in productions for ERP, CRM and custom web apps for many years.
Part of it's services and tools are based on webdo.com solutions, adapted for enterprises.

The web client uses the production latest versions for CSS, framework and utilities.

The jsapp.cloud is created and supported by Q-bis Consult SRL

You may ask your questions here.


1.2. Concept



What we want is to maximize the benefits of using and developing software while keeping budgets under control.

The solution we present is mainly related to resource allocation; the one metric that is easiest to consider is time , and the second is unit cost. Of course, completing something in a short time does not guarantee all the time the quality of the result, it depends on context; this should be addressed by using good tools.

One software development solution should be able to:
- Scale easily from a few users to thousands and more.
- Offer security by default.
- Provide development benefits.
- Offer easy-to-use interfaces.
- Have low maintenance costs.

Balancing demands to resolve them as quickly as possible within a budget.

Development:
Carefully choose tools that lower the required time for development while offering the necessary flexibility. Keep your programmers focused on the application's business aspects and user experience. Drop repeated, lengthy tasks.

Resource Consumption:
Balance requests using parallel scalability solutions and adjust the power of backend systems by leveraging unused power from client devices .

Maintenance:
Use cloud resources that are more reliable and typically offer management; maintain a clear and well-documented source code and utilize debugging options initially.

The proposed solution includes almost everything you need to implement, configure, develop and run a scalable web application:
- Backend services and cloud implementation solutions and scenarios.
- Default security and secured access rights.
- Solutions for frontend application development.
- Pre-made application modules that are necessary everywhere.


1.3. System Architecture




Web Clients ( notebook, tablet, smartphone 7-1,000,000)





The Internet Network






ThirdParty API; AI; etc



Firewall

Load balancers

1. API services
WebApp server
Authorization
SQL access API's
App API's
Others

2. API services
WebApp server
Authorization
SQL access API's
App API's
Others

3. API services
WebApp server
Authorization
SQL access API's
App API's
Others

...

N. API services
WebApp server
Authorization
SQL access API's
App API's
Others

CLOUD Resources
/S3, Route, SES, ML ...
Database server
/cluster

We use the Amazon AWS for CLOUD and infrastructure solutions.

Basic CLOUD services:
- S3 - file storage
- RDS / Aurora / PostgreSQL database
- Route53 - domain management
- SES ( app mail delivery )

Any other CLOUD service required for application business model can be added as a service or integration with third party services or API's.

Infrastructure resources:
- VPC
- load balancing
- security
- and/or fixed IPs

RESTful API webservices

Standard VPC:
- Linux Ubuntu
- NodeJS/services apps
- tools


1.4. Horizontal Scalability



Scalability is the measure of a system’s ability to increase or decrease in performance and cost in response to changes in application and system processing demands. Examples would include how well a hardware system performs when the number of users is increased, how well a database withstands growing numbers of queries, or how well an operating system performs on different classes of hardware. Enterprises that are growing rapidly should pay special attention to scalability when evaluating hardware and software.
Acording to gartner.com


There are two models to offer scalability: one that has obvious flaws, referring to vertical scalability , and the true solution, which is horizontal scalability.

We will discuss horizontal scalability and how it will be implemented.

Horizontal scalability requires parallel processing or the possibility to alter the number of available services resources at one moment depending on the expected number of requests. In our case, it refers to the number of VPCs that are used for the application services. In order to use horizontal scalability, you will need to use a sessionless connection between the client and services. Each request is treated separately and may be resolved by different service servers in a transparent manner.

The RESTful services we are using require authorization for each request; a JWT token is used and fits perfectly in the horizontal scalability model. The second part, which requires updating the number of allocated resources on demand, is solved gracefully by the AWS infrastructure in place.

We are using cloud resources wherever they fit the application's functionalities. Cloud resources are the best because scalability is inherent.


1.5. Security



At different levels, security is a must in today's environment . Communication is secured by encrypted layers (HTTPS); that is not new; this is mandatory. Resources access is protected by firewalls and security rules. The application services use a concept of "no trust," meaning that each request is verified and requires an authorization JWT token. There are no sessions or implicit access rights based on related access privileges. Tokens contain information related to the user and their user group membership; the services verify the token itself and the user's access rights. The authorization service is one of the most prone to being under attack; it has its own protections against brute force and other attack types. Protection layers are added for all services; for attacks like DDOS, the infrastructure's scalability will act.

The stored files are encrypted in S3 buckets. Additionally, there are no user lists with credentials or clear passwords even encrypted in the system's storage or database. The security model respects the legislation for personal privacy as specified by EU GDPR. The system is built to be used for sensitive data like medical records, financial and enterprise data by default. The file storage service model is not susceptible to a ransomware attack; it does not provide any required connection type for this kind of attack.


2. Getting started



jsapp.cloud offers the building blocks for web application implementation; it does not host the implementation. To give you full control over your data and the infrastructure used, the implementation utilizes resources from your own Amazon AWS account. We can provide basic support and assistance when needed. Upon request, we can offer additional support based on an agreement.

The implemented system requires cloud resources and services, as well as infrastructure. At this moment, the best provider for resources is Amazon AWS.
The configuration of the system takes some time; as some necessary steps may be delayed (like registering an AWS account, domain name acquisition, and others alike).
Initial settings for the AWS account and instllation are documented in next 2.x pages.


2.1 Requirements and recommendation



An Amazon AWS account is required. The account should be in the name of the final user (client). Navigate to https://aws.amazon.com/ and press the “Create an AWS Account” button. Next, follow the AWS website's requests. The requested email address can be provided by the client.
A credit card is required to validate the account.

A domain name is necessary for the software solution's web services address. You can use a domain name that you already have or purchase a new one. We recommend buying a new domain name from Amazon AWS using the Route 53 AWS service page with the created account. It will be useful to have all resources with one provider. AWS Route 53 offers also facilities for DNS routes to registered load balacers as A records (not IP only), with other DNS providers you will need to use CNAME instead.
If you use an existing domain name, check if you have access to edit DNS records for that domain (directly or through a third party).

An AWS S3 bucket is a file storage location. It should be created before implementation starts. (https://www.my-drive.cloud/files/Set_the_S3.pdf) Create a new bucket; the software solution will create related file structures in the bucket. Use the Amazon AWS S3 service page to manage the bucket. DO NOT set public access for the new bucket.


2.2 Access role (IAM) - AWS



The EC2 instances' software (the web services) requires access to the created S3 bucket. To grant access , an IAM role is required.
There are two options for security reasons:
- use the global access to the S3 policy
- create a new policy that grants access to the created bucket only (recommended)

Create an IAM role based on the S3 access policy.
The recommended option is to create an IAM policy that sets access to the created S3 bucket only. Next, create an IAM role based on the newly created policy.
By doing this, the installation will not interfere with any solutions currently in place or that will be implemented later. (https://www.my-drive.cloud/files/set_IAM.pdf)


2.3 Services Implementation



Install one EC2 instance from the Marketplace (https://www.my-drive.cloud/files/set_EC2.pdf).
Start an EC2 instance using an AMI from the Marketplace. Search for the "jsapp.cloud" AMI and choose the release.
It can be changed later, but considering the estimated system usage at the start, you can choose from different instance types. We recommend a T3a-micro for one hundred users with low access, a T3a-small for one hundred users with normal access, and a T3a-medium for more users or higher access levels, scaling allocated resources as the user base grows. These settings are recommended for average data transfer and loading per user. The system is scalable; more instances can operate in parallel to increase service availability.
Save and keep the created PEM access key secured at all times, as it is the only way to connect to your instance later for direct console management (SSH).
Once the EC2 instance is up and running: - use the AWS EC2 page to allocate the IAM role to the new instance.
This will grant access to the S3 bucket for the new instance. - check the security group of the new instance.



2.4 Security group



Security group settings: (use the AWS EC2 service interface)
The EC2 instances' security groups should allow access to the following ports (TCP):
- port 80 HTTP (a redirect page to the secured port)
- port 443 TCP (the application server)
- port 3200 TCP (the settings web app services)
- port 3220 TCP (the authorization web app services)
- port 22 TCP - set the filter to one IP address after installation (SSH management access)
- port 3330 TCP Database acceess API
- port 3400 TCP Database acceess API Management


2.5 Fixed IP



Add a fixed IP to the instance. For a simple installation (without an ELB balancer), a fixed IP is required.
If your DNS is hosted by AWS Route 53 and you are using ELB for service access balancing, a fixed IP is not necessary .
During the initial installation, for system configuration and a quick start, you may begin with one instance, set the system to work, and add scalability later.
Use the AWS EC2 service page to add an EIP ( Elastic IP) address.
Allocate the created EIP to the EC2 instance. Afterward , press "Actions" and "Associate Elastic IP address" to link the fixed IP to your EC2 instance.


2.6 DNS Settings



DNS Settings
In order to find and use your newly created web services, DNS records should be created or modified. You will need at least: an A record that points to the used IP address or a CNAME record that points to the ELB address. DNS settings interfaces will vary for different providers.
The AWS Route 53 DNS manager will allow you to create an A record that maps to an AWS EC2 ELB address, which is very handy. Amazon AWS sells domain names through the AWS Route 53 service web page.
We do recomend using AWS DNS management services and AWS Route 53.

Keep in mind that DNS settings propagation takes time. Your local system cache may store DNS requests, as well as the Internet ISP's infrastructure cache.


2.7 Application Settings



https://www.my-drive.cloud/files/settings.pdf
At this point , the application should be available via a web browser.
Navigate to your application settings interface:
https::3200 ( e.g., https://{my-server}.{ext}:3200)
The interface will use a self - signed SSL certificate at first start.
You should allow access from your browser to the settings web page; it is acceptable for the moment and the first configuration step. Add a SSL certificate to your installation later.

The first time, you will set the instance server and the system access settings:


Region – is the AWS region where your S3 bucket is
Bucket – the S3 bucket name
Passport - it is used to generate internal security keys and authorization JWT keys. It is generated first time, save it and keep it safe on your own device because it can not be recovered, it will be required when new VPC's are added.
The passport is linked to the S3 bucket used; you cannot use another passport for the same S3 bucket. Keep it safe in a secured place.
If this is the first server installation for the declared S3 bucket , you will need to set the administrator password; otherwise,
you must enter the administrator password to log in.
You will need to log in to start the web services on the EC2 server.

Add a certified SSL.
SSL certificates are sold by different providers. Free SSLs can be created from "Let's Encrypt."
Use an SSL certificate according to the implementation and your needs. ssls.com sells wildcard certificates that can be used on domains and subdomains, offering flexibility later.
The SSL certificate provides trust between a web browser and a web server/service. Use the My-Drive configuration to set the SSL certificate if it is the first server; each subsequently added server will read the stored certificate from the S3 CLOUD private bucket.

GET an SSL Certificate
Certified SSL certificates are mandatory. SSL certificate providers will use different methods to verify that you are the owner of the domain name for which you request a certificate .
The most commonly used methods are:
- Set DNS records as instructed to certify that you own the domain name.
- Place a text file in a specified location that can be used to download the file later (the location is under your domain name address).
- Receive an email at one domain name master address ( such as webmaster...).
https://green-lock.webdo.com is a utility provided to issue a FREE SSL certificate from Let's Encrypt in a short time.
It supports both DNS and FILE check methods.
The Let's Encrypt SSL certificate is valid for 90 days.
See the https://www.my-drive.cloud/services.html web page for recommended SSL certificate providers.


The DNS setting method fits better since the domain is used for web applications and services; an email may not be associated with it. The file method is also not very reliable..


2.8 Install a ssl certificate



GET an SSL Certificate
SSL certificate providers will use different methods to verify that you are the owner of the domain name for which you request a certificate .

The most commonly used methods are:
- Set DNS records as instructed to certify that you own the domain name.
- Place a text file in a specified location that can be used to download the file later (the location is under your domain name address).
- Receive an email at one domain name master address ( such as webmaster...).
The DNS setting method fits better since the domain is used for web applications and services; an email may not be associated with it. The file method is also not very reliable..

https://green-lock.webdo.com is a utility provided to issue a FREE SSL certificate from Let's Encrypt in a short time.
It supports both DNS and FILE check methods.
The Let's Encrypt SSL certificate is valid for 90 days.
See https://green-lock.webdo.com/ for a free certificate.

We do recommend SSLS.COM for paid SSL certificates.

Intall the certificate:
Use the settings web application to set your new SSL certificate. You will need to restart the web services after in order to use the new certificate



The SSL certificate consists of the certificate key and the complete chain of the certificate.
Ensure there are no empty lines at the beginning or end of the entered certificate/key text. Use the "Read Certificate " tab; if your certificate is not present , check the certificate and the key, and ensure no empty lines are included (top/bottom).

Reinstall an SSL certificate. Proceed as before: save the new certificate with the web app settings and restart the web services.


2.9 Start the web services



Use the settings web app INFO page to see the server status. Here, you can start or stop used services. The settings service runs by default. The “memorydb” web services server will not start without an SSL certificate set. The other services may not work as expected on mobile platforms like Android or iOS without a certified SSL certificate.




2.10 Install the web application



At this point, your system services are up and running; however, there are no web apps in place. Web apps are installed into the " Administrator " account in the "Applications/webroot/website" folder, but the drive file management is not in place. To install the required web applications, you will need to use the Settings app and install the app from the "Apps" tab.
The application is copied from a web address repository.

Required fields:

App Name:   - the application name, it is used in the installed applications list to identify your app.
Folder:   - the child folder to "Applications/webroot/website/" to install to ( it is created if not exist ).
Subdomain:   - leave blank at this time
Install from address:   copy next address   https://jsapp.webdo.com/install/1.3



2.11 Install the database



The system works with a PostgreSQL database by default. You will need to add an RDS PostgreSQL database to your AWS account. Choose the required capacity for your project; it can be changed later. ( the PosgreSQL can be installed to another VPC or can be installed elsewehre, we do recommend the AWS RDS/Aurora as their management is top class. )

There are specifications for the database fields, and some tables are mandatory for application processes.

You will need an interface to manage the database. We recommend pgAdmin v4 or later.
In order to use it, you should edit the VPC security settings and set access to the database from your IP address.

The access to the database, except for administration with pgAdmin, is made only through managed API services . The services implement security validation, CRUD operations, and more.

Configure the Application Data Access API to use your database server.
The address is: https://{your service address}}:3400 ( sample: https://subdomain.yourdomain.extension:3400 )

The first time, it will start with a settings page that will ask for the database address and credentials to access it. At this time, it will connect to only one database. The API manager will add an additional database to the same server named "rapidenterprise," which will store API-related information. See the documentation for the data access API in next chapters.

Database mandatory tables and table fields:
Necessary fields in tables:
id: character varying - the Primary key
user: character varying - records the last user who modified the record
createdAt: timestamp with time zone - moment of record creation
modifiedAt timestamp with time zone - last modified time

Tables:  actionlog,  zs_app_mods,  zs_app_roles,  zs_app_roles_links,  zs_app_routes,  zs_app_routs_links

actionlog ( SQL )
-- Table: public.actionlog
-- DROP TABLE IF EXISTS public.actionlog;
CREATE TABLE IF NOT EXISTS public.actionlog
(
   id character varying COLLATE pg_catalog."default" NOT NULL,
   username character varying COLLATE pg_catalog."default",
   logtime timestamp with time zone,
   tname character varying COLLATE pg_catalog."default",
   pky character varying COLLATE pg_catalog."default",
   pkyval character varying COLLATE pg_catalog."default",
   log text COLLATE pg_catalog."default",
   action character varying COLLATE pg_catalog."default",
   result bit(1),
   rerror text COLLATE pg_catalog."default",
   ip character varying COLLATE pg_catalog."default",
   origin character varying COLLATE pg_catalog."default",
   CONSTRAINT actionlog_pkey PRIMARY KEY (id)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.actionlog
   OWNER to postgres;


zs_app_mods ( SQL )
-- Table: public.zs_app_mods
-- DROP TABLE IF EXISTS public.zs_app_mods;
CREATE TABLE IF NOT EXISTS public.zs_app_mods
(
   id character varying COLLATE pg_catalog."default" NOT NULL,
   module character varying COLLATE pg_catalog."default",
   description text COLLATE pg_catalog."default",
   "modifiedAt" timestamp with time zone,
   "user" character varying COLLATE pg_catalog."default",
   "createdAt" timestamp with time zone,
   appname character varying COLLATE pg_catalog."default",
   CONSTRAINT zs_app_mods_pkey PRIMARY KEY (id)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.zs_app_mods
    OWNER to postgres;


zs_app_mods ( SQL )
-- Table: public.zs_app_roles
-- DROP TABLE IF EXISTS public.zs_app_roles;
CREATE TABLE IF NOT EXISTS public.zs_app_roles
(
   id character varying COLLATE pg_catalog."default" NOT NULL,
   role character varying COLLATE pg_catalog."default",
   description text COLLATE pg_catalog."default",
   "user" character varying COLLATE pg_catalog."default",
   "createdAt" timestamp with time zone,
   "modifiedAt" timestamp with time zone,
   CONSTRAINT zs_app_roles_pkey PRIMARY KEY (id)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.zs_app_roles
   OWNER to postgres;


zs_app_roles_links( SQL )
-- Table: public.zs_app_roles_links
-- DROP TABLE IF EXISTS public.zs_app_roles_links;
CREATE TABLE IF NOT EXISTS public.zs_app_roles_links
(
   id character varying COLLATE pg_catalog."default" NOT NULL,
   role_id character varying COLLATE pg_catalog."default",
   type character varying COLLATE pg_catalog."default",
   rname character varying COLLATE pg_catalog."default",
   "user" character varying COLLATE pg_catalog."default",
   "createdAt" timestamp with time zone,
   "modifiedAt" timestamp with time zone,
   description text COLLATE pg_catalog."default",
   field character varying COLLATE pg_catalog."default",
   rt boolean DEFAULT false,
   fv character varying COLLATE pg_catalog."default",
   CONSTRAINT zs_app_roles_links_pkey PRIMARY KEY (id)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.zs_app_roles_links
OWNER to postgres;


zs_app_routes ( SQL )
-- Table: public.zs_app_routes
-- DROP TABLE IF EXISTS public.zs_app_routes;
CREATE TABLE IF NOT EXISTS public.zs_app_routes
(
   id character varying COLLATE pg_catalog."default" NOT NULL,
   route character varying COLLATE pg_catalog."default",
   mod_id character varying COLLATE pg_catalog."default",
   description text COLLATE pg_catalog."default",
   "user" character varying COLLATE pg_catalog."default",
   "createdAt" timestamp with time zone,
   "modifiedAt" timestamp with time zone,
   CONSTRAINT zs_app_routes_pkey PRIMARY KEY (id)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.zs_app_routes
   OWNER to postgres;


zs_app_routes_links ( SQL )
-- Table: public.zs_app_routes_links
-- DROP TABLE IF EXISTS public.zs_app_routes_links;
CREATE TABLE IF NOT EXISTS public.zs_app_routes_links
(
   id character varying COLLATE pg_catalog."default" NOT NULL,
   type character varying COLLATE pg_catalog."default",
   rname character varying COLLATE pg_catalog."default",
   route_id character varying COLLATE pg_catalog."default",
   "user" character varying COLLATE pg_catalog."default",
   "createdAt" timestamp with time zone,
   "modifiedAt" timestamp with time zone,
   CONSTRAINT zs_app_routes_links_pkey PRIMARY KEY (id)
)
TABLESPACE pg_default;
ALTER TABLE IF EXISTS public.zs_app_routes_links
   OWNER to postgres;


3. Web client



The "Web client" refers to the web application delivered by default. It presents the web interfaces and the application structure to quickly build your new business user interfaces. The application comes with default modules that are needed for all applications , user management, application access rights management, CLOUD drive application, and reporting .

It is stored in a cloud S3 bucket file system and offers seamlessly the same resource to any web server in the load balancing pool by default. To achieve this , a CDN cloud file system like Cloudflare is typically used. Our solution uses customized web servers that connect and serve resources from your own secured S3 bucket. This solves the problem of having the same source files for horizontal scalability in a transparent manner.

We are using a single-page web application model based on the Vue.js framework and Bootstrap CSS. It can present the interface in supported languages. Labels are kept in JSON files for easy management. The context help files system is implemented (the F1 key is used to open the help file for the current app route). See the "Frontend Programming" chapter for more details.

It solves the problem of messy menus that are hard to follow and use. The only standard top menu is basic; next, there is a module selection menu (left modules list in the next image), and each module uses tabs for its routes (master tabs and tabs opened for business document interfaces). Document tabs can be closed, allowing you to have different documents open at once, such as invoices or whatever the module manages. Modules access is managed by the user groups roles, users will see only the modules they are alowed to see.

On-demand loading of the routes provides you with the ability to host a virtually unlimited number of routes with the same loading speed. A second benefit of this model pertains to application reliability and robustness. If there are errors on certain routes or components, the application will still start and function with other routes; from a continuous development or app maintenance perspective, this allows you to add features or modify routes while the application is in a production environment.

Reminder: You will have a starting project for a single-page web application with a standard UX that gracefully manages menus and offers, by default, internationalization, user help system, and on-demand loading for speed and reliability. See Frontend Programming for more.


3.1 Web drive



Based on the system web-drive APIs, this module offers file storage resources to your application users. It is not intended to replace the device file system; rather, it is a secure vault for files. It offers the possibility to share folders within groups or with users. The file storage is the AWS S3 bucket, and files are stored encrypted . The encryption / decryption is implemented on the data transfer stream, meaning that your files are always protected. Encryption uses AES256 and a large key. While it implements a RESTful standard API, the web storage API does not implement communication standards that can be used by ransomware malware.

The web-drive module is included by default in your startup application; it can be disabled in the app configuration file. It can be allocated to specific user groups.

The AWS S3 is probably the best implementation; it offers a flat access rate, high reliability, and multiple security measures. The DRIVE API offers options to use the selected S3 bucket like a drive with folder structures, copy/paste within the drive application, folder uploads and shared folders. The API is RESTful and requires JWT authorization. While it is a standard API, it does not implement standards used for third-party file sharing or access like WEBDAV; thus, it cannot be easily exploited by a very dedicated ransomware attack and cannot be exploited by a standard ransomware attack. The bucket is not seen as a whole drive but as a collection of users' drives , given that when a user's credentials are compromised, only that user may lose information. The logfile will save information related to file access, storing the IP address as well.

The DRIVE API can be used with a dedicated S3 bucket and will implement a structure of the resource ID keys; it cannot be used with random buckets and their files.
See the "backend" information for DRIVE API.


3.2 Web reports



The web reports module is a necessity for most business applications . It can be disabled and accessed only with specific group rights.

The web reports module implements:
- interfaces to manage the reports (categories, report lists, edit reports)
- interfaces to run and present the configured reports.

Available report types are:
- List grids (exports to Excel)
- Live CrossTab
- Live PivotTable (exports to Excel as a worksheet result)
- Graphs
- Dashboards (combine other report types into a report page with tabs)



Specific interface options and usage are provided with the application help base.


3.3 Users management



The user management is secured by default. There are users and user groups; each user can be part of one or more user groups. A user cannot be deleted from the system; however, it can be deactivated. Users can change their passwords. The username cannot be changed. You can change the first name, last name, or other user information, but not the username. A user management module is included in the web client application; it can be used by designated administrators or the system administrator. The user groups are used to allocate access rights within the application . There are no user lists in the PostgreSQL database; however, you may find usernames linked to some records , such as employee records or similar .

Specific interface options and usage are provided with the application help base.


4 Access rights



For access rights setup, the Setup module is used. Use the user management module to allocate users to groups. Rights are allocated to access modules, routes, queries, and tables for roles that are linked to user groups. By combining resources into sets and allocating those to user groups by roles, specific access can be achieved. Even if one user can access a specific route, it will have no data until rights are allocated to it.
Access to routes can be set into the module menu setup code also to add complexity to the model ( frontend programming ).
The backend resource access is verified at the request data access level by the API web service, part of the system's security.

Specific help pages for the Setup module are available in the application help manual.


5. Frontend programming



Before you begin,

The web client is based on Vue.js and Bootstrap. The current versions are 3.5 for Vue and 5.3 for Bootstrap. The jsapp.cloud platform offers a web client and base modules for the application. The backend can be used with any new web clients developed by third parties. We are using Vue.js since we found it most useful in our development model.

The CLOUD web application's file storage uses S3 or similar object storage technology. S3 is fast for delivering resources and is acceptable for file uploads . Today, the most commonly used development model for web applications is based on frameworks like Angular, React, or Vue, and the application generally needs to be built from the project using a utility for that. The result is a distributable project. This works well for the model where the entire application is loaded at the start.
The proposed web application model is based on loading resources on demand, which offers :
- a far better initial loading time
- a more robust application; the application will load even if there are hardcoded errors on some routes.
- easier debugging since the browser console will point you to the exact line of error.
The WEB CLOUD IDE is used to edit the web application where it is hosted, which increases development speed.
VueJS, in our case, can be used in development without a build; it has a clear structure for routing and component scripts, which allows for fast development.
Performance is somewhat similar to all web frameworks since the resulting web applications are used by humans. For business web applications, VueJS does an excellent job and fits our model well.

The development model addresses the foundation of the project from the outset by utilizing a clear project structure and easily readable script code for routes and components, thereby significantly reducing development and maintenance time.

The frontend project files, other than third-party files (VueJS, Bootstrap, Axios, jQuery, and others alike), are free to be used with the delivered backend installed from the Amazon AWS Marketplace only. See the License file for more information.


5.1 Project files



The application is hosted in Applications/webroot/website folder under administrator user account, this is the folder root for the web server.
The files structure as folow:

Project stucture is created with a new web app project.

  website:
      - index.html - the web application page
      - favixon.ico
        dst - application main folder
              config - configuration files folder
                  - config.json - configuration file, see the file for structure
                    labels - labels files for internationalization
                        - en.json - contry code . json ( see the en.json for structure )
                        - ...
              css
                  - default.css - the css file for the application
                  - bootstrap.css
                  - bootstrap.min.css.map
              help - a help file small vanila JS web application, it is used to provide content help files into the main application
                    css
                        - bootstrap files ( css and js )
                    files
                        - help pages HTML
                    img
                        - images used in help pages
              img
                  - images used in the application
              js
                  - custom.js - custom functions
                  - functions.js - application funtions
                  - webapp.js - main application js file
                    system
                        - JS files for Boostrap, Jquery, Axios, VueJS ...
  & {nbsp;           routes
                  - list.json
                    base- the base routes of the application
                        - list.json
                    start
                  ... other aplication modules

ROUTES folders, the list json file.


   [
      {
         "code": "base",
         "title": "Base routes",
         "path": "base",
         "enabled": true
      },
      {
         "code": "drive",
         "title": "WEB Drive",
         "path": "drive",
         "enabled": true,
      },
      {
         "code": "users",
         "title": "Users",
         "path": "users",
         "enabled": true
      },
      {
         "code": "setup",
         "title": "setup",
         "path": "setup",
         "enabled": true
      }
   ]

The list for default modules: (list.json in routes folder)
- base - has routes for the first loaded route (home) and the help route - short info related to the app.
- drive - the web drive application module
- users - the usere managements application module
- setup - the setup aplication module - sets the access rights

Each declared application module is stored in the routes folder in the specified path.
For an application module, there is also a list.json file containing the application routes, components, and the tab menu.

   {
      "app": "base",
      "path": "base",
      "routes": [
         {
            "route": "home",
            "path": "start",
            "html": "home.html",
            "code": "home.js",
            "components": [
               "app-submenu"
            ]
         },
         {
            "route": "help",
            "path": "start",
            "html": "help.html",
            "code": "help.js",
            "components": []
         }
      ],
      "components": [
         {
            "cname": "app-submenu",
            "path": "start/component",
            "html": "app-submenu.html",
            "code": "app-submenu.js"
         }
      ],
      "menus": []
   }

app: module code
path: module path relative to routes folder
routes: routes list ( html & js files for the route )
components: components registered for module
menus: tab menus for module (see next documentation for this)

The route is loaded in the application, as shown in the next image: ( base/ home route is presented )


5.2 webapp.js



The webapp.js file loads configurations and starts your web application.
It is stored in the /dst/js/ folder.

Generally, you will not need to modify it; however, if you need to extend the application with new features , you may need to edit it.

webapp.js loads the configuration at startup , loads the VueJS frameworks and utilities, and offers dynamic route loading functions and more .
Some functions are implemented in functions.js for convenience.
Your own new functions can be added to the custom.js file; see custom.js next.

The parent object offered to routes: (declared into Vue appliction system object)
chelp: - property - set by the current loaded route, offers the information neded to load context help file
userinfo: - object - current user information
authorized: - property JWT token
config: - object - configuration information
selectedORG - property - selected organization code ( if you will use the same app for an organizations group )
datamethod: - object - fucntions implemented by functions.js
addresses: - array - API access points and servers addresses
apps: - array - application modules
appsdata: - object - a storage for data between routes
appwindow: - object - application window and objects sizes and more
dataError: - object - set an error mesage
dataInfo: - object - set amn info message
ajax: - function - get access to ajax

Here "parent" will transfer only part of the application data to routes.

// index html
// webapp route loading tag
...
❬router-view :parent="system"❭❬/router-view❭ ...



5.2 functions.js



Implement default functions to be used in routes / components.
Use custom.js to add new appliction functions.

Some functions in functions.js are used by the application base.
Usable functions:
- showmodal
- hidemodal
- getOnlyDate
- sortarray
- ask4

showmodal
this.parent.datamethod.showmodal("modal-name")
Show the modal window, where modal-name is the modal div ID; the modal div should be in the current route's HTML.

hidemodal
this.parent.datamethod.hidemodal("modal-name")
Hide the modal window, where modal-name is the modal div ID; see showmodal.

getOnlyDate
Set a date from different formats includg timestaps to a YMD like format.
usage:
this.parent.datamethod.getOnlyDate(date,"YMD","-") // ( date, format - YMD, YDM, DMY ... , separator ).
it is useful to prepare date fields

sortarray
this.parent.datamethod.sortarray(array,field,order) // (array,'firstname','asc' - asc/desc )
Sort an array.

ask4 - see data access.


5.4 custom.js



Implement some custom functions into the application.
The JS file is dst/js/custom.js

Sample: - implement "myfunction"

'use strict';
// custom.js - app custom functions;
//
var axios = axios;
var $ = $;
var extra = {
  myfunction:function(a,b,c){
     var ret = a+b+c;
     return ret;
   }
};

Can be used in routes:
var sum3 = this.parent.extra.myfunction(10,15,25);


5.5 Application Module



The web application is organized into modules.
One module is a collection of routes that are related in some way to the application's business.
Default modules are Reports, User Management , Web Drive , and Setup.

In the standard user interface, the modules list is positioned on the left.
It is filtered for each user according to their access rights based on group membership .

The modules link information are in dst/config/config.json - lmenu array

// sample:

...
{  "_name": "reports-start",
 "_route": "/reports-start",
 "_text": "Reports",
 "_title": "WEB reports",
 "_icon": "pulse-outline",
 "app": "reports",
 "path": "reports",
 "label": "lblReports",
 "titleLabel": "lblReportsTitle"
}, ...

Modules are declared in dst/routes/list.json ( sample for Web reports )

// sample:

...
 {
  "code": "reports",
  "title": "WEB reports",
  "path": "reports",
  "enabled": true
 },
...

Files for one module are stored in "routes" folder in the path name folder for the module. The module has its own list.json . Sample list.json for the Web reports module.

app: - module code
path: - module path in "routes" folder
routes: list of routes in module
components: list of declared components ( related to this module )
menus: list of declared tabs in this module ( fixed tabs )
// sample:

{
 "app": "reports",
 "path": "reports",
 "routes": [
  {
   "route": "reports-start",
   "path": "start",
   "html": "reports-start.html",
   "code": "reports-start.js",
   "components": []
  },
  {
   "route": "setup-reports",
   "path": "setup",
   "html": "reports-setup.html",
   "code": "reports-setup.js",
   "components": []
  },
  {
   "route": "edit-report",
   "path": "setup",
   "html": "edit-report.html",
   "code": "edit-report.js",
   "components": []
  },
  {
   "route": "run-report",
   "path": "runreport",
   "html": "run-report.html",
   "code": "run-report.js",
   "components": [
    "grid-var"
   ]
  },
  {
   "route": "test-reports",
   "path": "test",
   "html": "test-reports.html",
   "code": "test-reports.js",
   "components": []
  }
 ],
 "components": [
  {
   "cname": "grid-var",
   "path": "runreport/component",
   "html": "grid-var.html",
   "code": "grid-var.js"
  }
 ],
 "menus": [
  {
   "_name": "reports-start",
   "_route": "/reports-start",
   "_text": "lblReports",
   "_title": "lblReports",
   "_icon": "calculator",
   "tp": "master",
   "app": "reports"
  },
  {
   "_name": "setup-reports",
   "_route": "/setup-reports",
   "_text": "lblAccSetup",
   "_title": "lblAccSetupTitle",
   "_icon": "settings",
   "tp": "master",
   "app": "reports",
   "isadmin": true,
   "admingroup": "reportadmin"
  }
 ]
}


5.5.1 Route



The system's route, based on VueJS's route-view, consists of at least two files: one HTML file for the view and one JS file to control it. One route may also include a CSS file and components (see components next). The route is declared in the module "list.json." . Files for one module are stored in the "routes" folder, in the path name folder for the module, along with a subfolder named according to your policy (i.e., route scope). Each route should be declared in the module's list.json file.

// sample:

{
 "app": "reports",
 "path": "reports",
 "routes": [
  {
   "route": "reports-start",
   "path": "start",
   "html": "reports-start.html",
   "code": "reports-start.js",
   "components": []
  },

route - route name
path - module subfolder name
html - the html file
code - the js file name
components - an array of components used into the route, put here the components that are NOT loaded as default components by first route "home".

Minimal route HTML and JS:

HTML

<div class="row nomargin">
  <div clsss="col-md-12">
   <p>Help</p><<br>
   App:{{appname}}<<br>
   {{organization}}<<br>
   <a href="https://web.jsapp.cloud/dst/help/#info" target="_blank">help</a><<br>
   <p><br>
   {{parent.labels}}<<br>
   </p>
  </div>
</div>

VueJS model is used to display or edit data.

JS

'use strict';
export var component = {
 props: ["parent"],
 data(){
  return {
   isf:false,
   appname:"base",
   helpfile:"info",
   organization:this.parent.selectedORG,
  };
 },
 created(){this.parent.chelp = this.helpfile;this.fetchData()},
 watch:{'route':'fetchData'},
 methods:{
  fetchData(){
   var td = this;
   console.log("Start help - fecthData:",td);
   console.log("parent:", this.parent);
   console.log(td.parent.datamethod.getOnlyDate(new Date(),"ymd","-"));
  }
 }
};

The JS file's "parent" property (props list) contains data and system functions required by the application. VueJS does not support "$parent" from v3. The created function, parent.chelp, sets the interactive help link name. The fetchData method is used to load the required data as needed .

To load a route use parent.croute function:
...
this.parent.croute(route);
where route is:
var route = {
   _name: route name,
   _route: route,
   app: app name
};

Routes are generally loaded from a system menu or a menu substitute. The UI-left application modules list loads the default route for the module. Each module has a tab-based menu that loads routes. Additionally, routes can be loaded , and temporary tabs can be added to the default available module tabs as needed.

The "parent.croute" is used to load routes when needed. If a route is already loaded once, it is stored and used on subsequent requests.
See the "app-submenu" component described in components.

Application modules tabs submenu is declared into the list.json file of the application module into menus array:

"menus": [
 {
  "_name": "reports-start",
  "_route": "/reports-start",
  "_text": "lblReports",
  "_title": "lblReports",
  "_icon": "calculator",
  "tp": "master",

  "app": "reports"
 },
 {
  "_name": "setup-reports",
  "_route": "/setup-reports",
  "_text": "lblAccSetup",
  "_title": "lblAccSetupTitle",
  "_icon": "settings",
  "tp": "master",
  "app": "reports",
  "isadmin": true,
  "admingroup": "reportadmin"
 }
]

There are special routes that load documents or specific data. In the system, these are generally found under a closable tab (module menu) , such as a report to run or an invoice etc. Since you may open that route multiple times for different document numbers or different reports in the Report module case, data for that route should be stored somewhere and retrieved when a document is selected from the tabs menu. Tabs are stored in the parent.apps array for each app module. Parent .apps store the application module's global information ; parent.apps[n].menus store the app module's tabs submenu. For each submenu route, you may store data in its "menu" object. The route should check in the fetchData method and retrieve the stored data from the "menu" object for the selected document (case for temporary menus used for documents of the same type and alike).

routes for document type information or alike possible implementation:
("document" is a record object like an Invoice, a report etc ) In route .js file, data property has a property named "tab"

This kind of route is not loaded from a menu, but from another route from a list or an action, when it it requested, first it is need to be configured into the system.
You know the app module name at when you load add a new menu, generally is this.appname Find the app object in parent.apps array list.
Into the appmodule object, menus list you need to add a new "menu".
Sample for reports module, run report route:

...
function loadDoc(a,doc){
   if(!doc.reportset){
    doc.reportset = {};
   }
   doc.reportsettings = doc.reportset;
   var newtab = {
     _name: "run-report",
     _route: "/run-report",
     _text: "lblSpace",
     _title: "lblSpace",
     _icon: "newspaper-outline",
     tp: "slave",
     app: "reports",
     tid:doc.id+"run",
     tn: doc.report_name + " - " + doc.category_name,
     editable:true,
     data:{
     ....
     }
   };
   a.menus.push(newtab);
   try {
    td.parent.selectnewtab(td);
   } catch(x){
    console.error("Error:",x);
   }
}
....

Here "a" is the app module object, doc is the document to be loaded
_name: route name;
_route: route;
_text: text label in menu;
_title: title in menu;
_icon: used ionicon icon name;
tp: "slave" for a menu/tab that can be closed;
app: app module name,
tid: one ID for the menu it shoul be unique,
....
data: object, put here data that you have for the loaded document and you want'it stored when document is changed ( navigation ).
parent.selectnewtab - will select the last added menu and load it's route/data. ( td is "this" route, the route that load a new one...)

In fecthData(): retrive stored data for this route

...
var td = this, dm=td.root.datamethod;
td.parent.apps.forEach(function(a){
  if(a.app==td.appname){
    a.menus.forEach(function(m){
    if(m.class=="active"){
     td.tab = m;
    }
   });
  }
});
...

5.5.2 Component



The system uses Vue components. Components are loaded as needed by the dynamic loading model used by "croute". Each component have a HTML and a JS file for view and control. Components are declared into the application module list.json file.

// sample:

{
 "app": "reports",
 "components": [
  {
   "cname": "grid-var",
   "path": "runreport/component",
   "html": "grid-var.html",
   "code": "grid-var.js"
  }
 ],

Components are loaded dynamically when a route is loaded; used components are required as well. The components are declared in the route HTML view; however, in order to load them, component names should be included in the route description's "components" array in list.json. You may not add the component names to the route description for default components.

Default components do not have a special status; they are declared and loaded by the home route like any component and, thus, added to the system components list, making them usable later in any route. See the home route, the base application module where the "app-submenu" component is declared. Add components that are used in more than one module to the home route in the base module as default components.

The component name should be unique; if you reuse a component name, the first one loaded will be used as it is found in the system components list.


app-submenu component

It is used as a tab based submenu into the application. It can be set to have a default structure and the posibility to use dinamic added tabs (can be closed)

Sample image - Reports module.

Closable tab menu, used for routes that can be opened multiple times (when you open three different invoices or anything similar).

Usage:
...
<app-submenu :root="parent" ref="appmenu"></app-submenu>
...

root - is the system data and modules that can be used into components, tranferred from the route where the compoinent is used.

The app-submenu are in dst/routes/base/start/component
- app-submenu.html
- app-submenu.js

To add a temporary tab, when you open a unique document route ( like open a report in Reports module ):
The new tab menu should be added into the application module object menus list. See the "routes" help page for details.


5.6 CSS



The default CSS file is dst/css/default.css.
The web application uses Bootstrap CSS.

CSS files can be set on each route HTML file as well if they are required.
In this case, have the route CSS file stored in the same folder as the route files.


5.7 DATA access



Data access is used first by fetchData in routes JS files and anywhere is needed later. The backend system offer API methods for managed CRUD operations for PostgreSQL database. One service is used as default for data access. It is implemented by functions.js,
the "ask4" function uses Axios to send requests to a web service API.

it can be used from a route as this.parent.datametod.ask4 function method
like in this.parent.datametod.ask4(system_data,service_name,acces_point,api_name,method,data,token,callback_function,headers)

parameters:
system_data: system data - in routes it is this.parent
service_name: service name - a service name found in config.json addresses
acces_point: api access point - the API access point
api_name: api name - the API name
method: request method ( GET, POST, PUT, DELETE )
data: sent data ( JSON )
token: the JWT token, false if there is no Bearer token used, {t:"token",v:"Authorization type"}
callback_function: function used as callback to check the request result,
headers: NOT mandatory, additional request headers in case

headers format if necessary is:
[
   {h:"header name", v:"header value"}
]

Ex:

[
   {h:"Content type", v:"Application/Json"}
]

Sample (js):

dm.ask4(this.parent, "server", "extra", "admin/getusers", "POST", {nro:10000},{
         t:"Bearer",v:this.parent.authorized
      },function(e,d){
});


Help for the data access API accepted API's is provided

https://{your application address}:3400/pages/help.html, help link from the backend query data access management web application.

See backend data access for the data API provided.


5.8 File access



Files can be linked to records in the database where they should be used.
To offer more flexibility, in the user interfaces near structured data tables/fields,
you may attach files. Files should not be stored in the database ; instead, links to the files or file access keys are stored in the database.



see the backend file access API for programming details.

Sample code to download a file from a database table record link:
consider the record like:
{id:"recordId",filename:"my file name.docx", fpath:"Applications/appfiles/...../file_code.docx", ... }

HTML: (route / component html )

<span class="link" v-on:click="downloadFile(f)">{{f.filename}}</span>

JavaScript: (route / component js)

function downloadFile(file){
   // file - file record , filename, folder
   var dm = this.$parent.$parent.datamethod;
   var folder = file.filepath;
         var rpath = "?file=" + window.btoa(file.filename) + "&fpath=" + window.btoa(folder + "/"+file.id);
         console.log(rpath);
         var td = this;
         // check if file exist //
         dm.askfor("server", "extra", "headappfile"+ rpath,"GET",{},{t:"Bearer",v:td.parent.authorized},
            function(e,d){
            if(e){return alert("File not found!")}
               var rd = new Date().getTime();
               // download file
               window.open(dm.addresses.server + "/extra/getappfile" + rpath+"&token=" + tda.$parent.$parent.authorized) + "&rd=" + rd;
            }
         });
},

File upload:
file object comes from an input file document element.
JS sample: ....


The files management module offers CLOUD files storage maangement for each user. Folders can be shared to users groups and users.


6. Backend



The platform offers backend support for your WEB application.
Default backend services covers:
- authorization API
- PostgreSQL managed CRUD API
- webserver
 - S3 files API
 - application base API

The default delivered Web Application client interfaces and primary modules, when used, implements the backend API's.
See the backend API documentation next.

In order to extend the backend capabilities, custom API interfaces can be added. See programming next.


6. Backend API



Authorization API

authorization (login)

method: GET
url: “https://<authserver>/users/login”
headers: {
 'Content-Type': "application/json; charset=utf-8",
 'Authorization': “BASIC <authstring>”
}
authstring = Base64( “<user>:<password>” )
Response:
{login:”OK”, token:<JWT token>}


update ( password, last name, first name - by user)

method:POST
url: “https://<authserver>/admin/updateme”
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <token>”
}
data:{
 f:<first name>
 l: <last name>
 pwc: <new password>
}
Response:
{token:<JWT token>}


Administrator:

Authorization for administrator (token)
Used only by the “administrator” account, returns an additional token requested for users management requests:
method:POST
url: “https://<authserver>/admin/admlogin”
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <JWT token>”
}
data:{}
Response:
{token:<token>}

Create user

method:POST
url: “https://<authserver>/admin/createuser”
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <adm credit>”
}
data:{
 user:<user>
 firstname:<first name>
 lastname: <last name>
 pwc: <password>
}
Response: { _action: "create", _uid: "system", _xt: "<DateTime>", f: "<first name>", l:”<last
name>”, id:”<id-user>”,u:”<user>”}

User Update (by administrator)

method:POST
url: “https://<authserver>/admin/updateuser”
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <adm credit>”
}
data:{
 uid:”<id-utilizator>”,
 user:”<utilizator>”,
 update:{
  f:”<first name>”,
  l:”<<lastname>”,
  newpwt:”<new password”>
 }
}
Update – only new values should be here.
Response:
{
 msg:”write data”,
 response:{
 allok:true,
 data:[
  id:”<id-user>”,
  f:”<first name>”,
  l:”<last name>”,
  u:”<user>,
  g:[
   {g:”<group>”,id:”<id>”}
  ],
  _action:”update”,
  _uid:”system”,
  _xt: “<DateTime>
  ]
 }
}
Response data is response.data[0]

Users List:

Returns users list. Parts of the list can be requested.
method:POST
url: “https://<authserver>/admin/getusers”
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <adm credit>”
}
data:{
 nro:<records number>,
 lastfrom:<requests from number>
}
data.lastfrom it is not mandatory, can be used to request users starting with one number.
Response: (type array)
[
 {
  id:”<id-user>”,
  f:”<first name>”,
  l:”<last name>”,
  u:”<user>,
  g:[
   {g:”<group>”,id:”<id>”}
  ],
  _action:”update”,
  _uid:”system”,
  _xt: “<DateTime>
 }
,…
]

User search:

method:POST
url: “https://<authserver>/admin/finduser”
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <adm credit>”
}
data:{
 user:”<user>”
}
response: same as previous (users list)

Users list information:

method:POST
url: “https://<authserver>/admin/usersinfo”
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <adm credit>”
}, data:{}
Response: number of the users into the system

Create users group

method:POST
url: “https://<authserver>/admin/creategroup”
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <adm credit>”
},
data:{
 g:”<group>
}
Răspuns:
{
msg:”write data”,
response:{
 allok:true,
 data:[
  {
  g:”<group>”,
  id:”<id grup>”
  }
 ]
 }
}

Update group information

method:POST
url: “https://<authserver>/admin/savegroup”
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <adm credit>”
},
data:{
 id:”<id grup>”,
 u:{
  id:”<id user>”,
  u:”<user>”
 }
}
Response:
{
 msg:”write data”,
 response:{
  allok:true,
  data:[
   {
    id:”<id user���>,
    f:”<first name>”,
    l:”<last name>”,
    u:”<user>”,
    g:[
     {g:”<group>”,id:”<id grup”>},...
    ]
   }
  ]
 }
}

Groups list

method:POST
url: “https://<authserver>/admin/getgroups”
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <adm credit>”
}
data:{nro:1000}
Response:
{
 records:[
  {g:”<grup>”, id:”<id grup>”}
  ,...
 ]
}



S3 files access API

The backend system offers access to an S3 bucket for file storage and management. It offers support for one bucket access and will add additional files and structures to it in order to work. The users' information also utilizes the same S3 bucket.


Default folders

Returns default folders information ( root ). If the user is new it creates the initial folders structure. Same response is returned in both cases.

method:POST
url:"https://<appserver>/sfd/defaults"
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <token>”
}
data:{}
Response:
{
 apps:true,
 fixed:true,
 fldname:”Root”,
 folders:[
  {fldname:”Documents”,id:”Documents”},
  {fldname:”Files”,id:”Files”},
  {fldname:”Trash”,id:”Trash”},
  {fldname:”Applications”,id:”Applications”}
 ],
 id:”Root”,
 parentid:”Root”,
 ownerid:”<cale>”
}



Create folder

method:POST
url:"https://<appserver>/sfd/createfolder"
headers:{
“Content-Type”: “application/json; charset=utf-8”,
“Authorization”:”Bearer <token>”
}
data:{
 "folder": "<foldername>",
 "parentid": "<folder path>"
}
Response:
{
 apps:false,
 fixed:false,
 fldname:”<foldername>”,
 folders:[],
 id:<”foldername”>,
 parentid:”<calea catre folder>”,
 ownerid:”<cale initiala>”
}



Delete folder

Before "delete" check folder information ( if it has subfolders ) and if there are files into the folder.

method:POST
url:"https://<appserver>/sfd/deletefolder"
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <token>”
}
data:{
 "folderid": "<folder path>"
}
Ex: {
 "folderid": "Documents/n1/n2/n3"
}
Response:
{folderid: "<calea catre folder>"}
Ex: {folderid: "Documents/n1/n2/n3"}


Folder information: (include subfolders names)

method:POST
url:"https://<appserver>/sfd/folderdata"
18/22headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <token>”
}
data:{
 id: "<folder path>"
}
Response:
Ex: {
 "data": {
 id": "n1",
 "fldname": "n1",
 "createdAt": "2021-02-14T06:54:34.938Z",
 "rights": {},
 "folders": [
  {
  "fldname": "n2"
 }
 ],
 "fixed": false,
 "apps": false,
 "ownerid": "GLJTSFUTTXJLWGYH",
 "parentid": "Documents"
}



Folder files:

method:POST
url:"https://<appserver>/upload/s3enc/sfd/folderfiles"
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <token>”
}
data:{
 id: "<cale folder>"
}
Response:
{
 "files": [
  {
  "name": "info.txt",
  "size": 2,
  "createdAt": "2021-02-08T15:06:33.000Z"
  }
 ],
 "parentid": "Documents"
}



Copy files:


method:POST
url:"https://<appserver>/sfd/copyfiles"
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <token>”
}
data:{
 files:[
  {
   id:”<file.name>”,
   ext:”<extension>”,
   parentid:”<path to file>”,
   preext:”<just filename>”
  }
 ],
 folderid:”<new path>”
}

Sample:
data: {
 files:[
   {id:”info.txt”,ext:”txt”,parentid:”Documents/test”,preext:”info”}
  ],
 folderid:”Files/test2”
 }

Response:
{
"files": [
  {
   "label": "info.txt",
   "id": "info.txt",
   "parentid": "Documents",
   "sdate": "2021-02-08T15:06:33.000Z",
   "size": 1,
   "preext": "info",
   "ext": "txt”,
   "nid": "info.txt"
  }
 ],
"errors": []
}

Delete files


method:POST
url:"https://<appserver>/sfd/deletefile"
headers:{
 “Content-Type”: “application/json; charset=utf-8”,
 “Authorization”:”Bearer <token>”
}
data:{
 opt:false,
 files[
  {id:<filename>}
  ],folderid:<id folder>
}

Ex:
data = {files:[{id:”file1.xlsx}],folderid:”Files/test_folder”,opt:false}

Response:
data:{
 errors:[],
 files:[{id:<filename>}]
}
Deleted files are moved to the Trash folder.

File upload


method:POST
url:"https://<appserver>/upload/s3enc/" + folderid + "?token=" + key;
data:{s3enc:<fileobject>}
“multipart form upload”
Folderid – folder path, replace “/” with “*” and use encodeURI(folderid)


Sample response:
{
 ename: "s3enc",
 cnt: "Content-Disposition: form-data; name=\"s3enc\"; filename=\"q-plan.docx\"",
 contenttype:"application/vnd.openxmlformats-fficedocument.wordprocessingml.document",
 filename: "q-plan.docx",
 name: "q-plan.docx",
 start: "-----------------------------187855873322272168611499597250",
 end: "-----------------------------187855873322272168611499597250--",
 poz: 220,
 tpe:"Content-Type:application/vnd.openxmlformats-officedocument.wordprocessingml.document"
}


File download


method: GET
url:”https//<appserver>/simple/getfile/<fileinfo>
 query:{
 token:<token>
}

fileinfo = (filepath + “/”+filename).replace(replace(/\//g,"*" )

Ex: “Applications*folder*new*info.txt”
The Response has “headers” set in order to open “SaveAs” in browser.


Programmable web services support


The application servers offers support for software application development offering its
services as standard API’s.
New services can be added to existing services for different purposes.
The web services interfaces (API) use open standards and respect RESTful principles.

Web Server for web apps and presentation web pages


Two standard web ports are opened:
- port 80, opened for a redirect page that send the request to the 443 secured port
- port 443, secured port opened by the application server
The application server serves specific web services for drive application and can server also static web pages stored into the private S3 CLOUD.
The web server service benefits the scalability of the entire system; the web pages are stored in CLOUD and are secured.
Text editors are available for the website files, the access is granted using the “administrator” account and the web drive application; the location is “Applications/webroot/website”.
The Administrator “Applications/webroot/website” folder is public. Files can be read with a web browser using the WebApp web address. Es: https://<web address>/index.html

PostgreSQL managed CRUD database acccess API

Documentation help file is found in the API management web application.


6. Backend programming




7. Third party integration



The system offers the possibility to extend its API base.
Connecting to modern REST third-party APIs is easy; on the other hand, you can create your own API connector to almost any legacy third- party application via a custom API.

Sample: (FTP/SFTP)
- A third party offers information in an SFTP folder.
- Add a custom API that holds the credentials, connects to the SFTP folder and do whatever is necessary.
- Your client app will securely connect to the custom API as with any other.

There are legacy apps that still use FTP/SFTP, DCOM or SOAP for interoperability.
Implement custom APIs as easy as possible or just create an API connector to existing API brokers.


8. AI



Integrating AI services is as easy as integrating any other third-party REST APIs. The AI interfaces are new and generally use a REST API as the default standard.

The business logic of your application module can be as complex as you envision. Third-party or AI services can help you solve problems faster and also distribute your system load, helping you scale more quickly .


9 Roadmap



We will continue to maintain and develop new features for this web application development model. New features will be added according to the development strategy and partners' requests. Under development tools refers to AI integration.
While AI has recently been introduced into the market, it has proved its power. Although AI interfaces can be easily used in your modules, we will soon add an AI-assisted module construction wizard to the CLOUD IDE to help you start a new module faster .


10 Technical support



The solution implementation may require IT and Amazon AWS knowledge. As a software application solution that requires installation and implementation on the CLOUD provider infrastrucure with different scenarios under a final client account, technical support may be subject to the implementation contract with an software integrator. Please check the solution presentation web page for more details.

Basic technical support is offered by email to a system administrator in case there is no integrator that provides technical support or maintenance (jsapp@qbis.com). Depending on the complexity of requests, there may be additional fees per intervention if there is no help desk contract agreement. The fee levels relate to the complexity and confidentiality agreements required for the operation.
The ticketing help desk will be commercially available in short time.


11. License



THIS COMMERCIAL LICENSE AGREEMENT (“AGREEMENT”) IS A LEGALLY BINDING
CONTRACT BETWEEN THE INDIVIDUAL WHO INSTALL THE SOFTWARE (“YOU”) AND
THE LICENSOR, THAT SHOULD BE READ IN ITS ENTIRETY. THIS IS AN AGREEMENT
GOVERNING YOUR USE OF FREE SOFTWARE, FURTHER DEFINED HEREIN AS
“SOFTWARE SOLUTION”, AND THE LICENSOR OF THE SOFTWAREIS WILLING TO
PROVIDE YOU WITH ACCESS TO THE SOLUTION ONLY ON THE CONDITION THAT
YOU ACCEPT ALL OF THE TERMS AND CONDITIONS CONTAINED IN THIS
AGREEMENT. YOU ARE DEEMED TO HAVE READ, UNDERSTOOD AND ACCEPTED ALL
SUCH TERMS AND CONDITIONS UPON IMPLEMENTING THE SOLUTION.THIS
COMMERCIAL SOFTWARE SOLUTION IS COPYRIGHTED AND THE OWNER OF THE
COPYRIGHT CLAIMS ALL EXCLUSIVE RIGHTS TO SUCH SOFTWARE, EXCEPT AS
LICENSED TO USERS HEREUNDER AND SUBJECT TO STRICT COMPLIANCE WITH THE
TERMS OF THIS AGREEMENT. IF YOU FAIL TO ABIDE BY ANY OF THE TERMS AND
CONDITIONS SET FORTH HEREIN, YOUR LICENSE TO USE SUCH COMMERCIAL
SOFTWARE SOLUTION SHALL BE IMMEDIATELY AND AUTOMATICALLY REVOKED,
WITHOUT ANY NOTICE OR OTHER ACTION BY THE LICENSOR.

Software: jsapp ( https://www.jsapp.cloud )
License type: Commercial
Licensor: Q-Bis Consult S.R.L. ( www.qbis.ro )
1. Description:
The JSApp implementation utilizes various services to address all requests (the software solution). The software solution employs cloud and infrastructure services from Amazon AWS to provide easily usable services for remote work ; it focuses on security and scalability by offering simple web interfaces and integration with third-party solutions based on open standards. Please visit the presentation website for more details. The copyright owner of the software solution applications is Q-Bis Consult SRL (the provider or the licensor).
Open standards and open source were used to construct the applications and services; however, the software solution's copyright owner is Q-Bis Consult SRL, with exceptions granted to external resources.
2. Usage: The software comes pre-installed in Amazon EC2 AMIs found in the AWS Marketplace.
The server applications (services) can only be installed as specified by the provider using Amazon AWS AMIs
from the AWS Marketplace in accordance with the recommended AMI types (see the installation guide here: https://www.jsapp.cloud/services.html).
Files found in the subsequent sub-folders and recurring folders are under Q-Bis Consult copyright:
- auth
- memorydb
- web80
- webapp
- settings
- psql

You cannot copy or move the software solution to other server instances (AWS EC2 AMIs ) or to other computers outside of Amazon AWS. You may modify existing files to enhance or expand functionality; however, you cannot distribute, move, or copy the modified software solution to another server without approval from the software solution provider.
The following frontend application modules delivered with the solution can be used only with the original backend that operates on the previously described Amazon AWS AMIs:
- the webapp base
- the web drive application
- the web reports application

3. Trial:
A 15-day trial period is offered for software services; the AWS infrastructure cost is not included in the trial period.

4. Fees:
The software comes pre-installed in Amazon EC2 AMIs found in the AWS Marketplace.
Software service fees are included in the price of the VPCs rented from AWS.
The AWS list price for the EC2 AMI details the cost for AWS infrastructure and the price for software. Prices are charged per hour.


5. Disclaimer:
The software solutions used are tested and have been in use since 2014.
Due to the significant difference between the cost of the solution and the value of the stored data, the software for the server services and web application is delivered "as is" without any warranty of any kind; Q-bis Consult SRL, the provider, cannot be held liable for any data loss that may occur while using the software for any reason . In the event that local law establishes that compensation is required, the compensation cannot exceed the value of the paid service for the software for one month, but it will not exceed 50 USD .

6. Technical support :
Implementing the solution may require IT and Amazon AWS knowledge; please check the solution presentation web page (https://www.jsapp.cloud/services.html) for a solution integrator who can assist with implementation and customization.

Basic technical support is offered by email to a system administrator in cases where there is no integrator providing technical support or maintenance (jsapp@qbis.ro). Depending on the complexity of the requests, there may be additional fees per intervention when no maintenance contract is in place . The fee level is related to the complexity and confidentiality agreements required for the operation; however, it does not exceed fees accepted in the IT industry.

As a software application solution that requires installation and implementation with the CLOUD provider under a final client account, technical support may be subject to the implementation contract with an integrator. Q-bis Consult provides a list of software integrators on the product presentation web pages.


© 2025 Q-Bis Consult