0% found this document useful (0 votes)
29 views

User Guide Redacted

This guide summarizes a CodeGuardian website that allows customers to subscribe to cybersecurity services. The tech stack includes Node.js, Express, MySQL, Stripe, and other tools. Users can register, subscribe to services, schedule consultations, and submit requests. Admins can manage requests and consultations. The document outlines customization options like pricing plans, Calendly settings, and subscription features. It also notes a known bug with Calendly appointments.

Uploaded by

api-694008769
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views

User Guide Redacted

This guide summarizes a CodeGuardian website that allows customers to subscribe to cybersecurity services. The tech stack includes Node.js, Express, MySQL, Stripe, and other tools. Users can register, subscribe to services, schedule consultations, and submit requests. Admins can manage requests and consultations. The document outlines customization options like pricing plans, Calendly settings, and subscription features. It also notes a known bug with Calendly appointments.

Uploaded by

api-694008769
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

CodeGuardian User Guide (CSUMB Capstone 2023)

Project URL: https://cybersecurity0-f5f3aa9877e5.herokuapp.com/

Purpose: This guide will include details about the tech stack, user and admin features, a
database diagram, a known bug, and customization instructions.
Description: This website allows customers to subscribe to the cybersecurity services of our
client Sam Abdul. The landing page includes the pricing table from Stripe, services offered, and
testimonials from happy customers.

Tech Stack Used

● Node.js + Expres.js
● Bcrypt: Used to hash passwords before being stored in our database, 10 salt rounds.
● Calendly: Used to book consultation appointments + webhook for the database.
● Express rate-limit: To prevent DOS and brute force attacks
● Express session: Used for our customers/admins to log in with a session
● Google Cloud Storage node package, multer node package, and the bucket
configuration to store uploaded files from the customer/admin portal and download them
from there. See “Google Cloud Storage bucket setup” below for more details.
● MySQL: Database used.
● Nodemailer: Used to send emails for forgotten passwords. We created a sender email
[email protected] password: , but this can be replaced
if you want the verification code to be sent by a different email. See “Updating
Nodemailer Google Account” below for more details.
● OAuth: Gives our users the ability to log in without a password with Google. See “Google
OAuth setup” below for more details.
● Passport: Part of the OAuth integration.
● Stripe: Payment processing, pricing table, customer portal, billing sessions, including
signature verification to prevent malicious actors from spoofing requests.

User Features
A customer can register with us using either an email and password or via Google
OAuth. Once registered they can access the customer portal, which will show the pricing table
again but this time it will be interactable. When they choose to subscribe Stripe will create a
billing session where the customer can enter their payment information securely handled by
Stripe. Their card details will NEVER be stored on our database or even interact with our server.
After a successful checkout, the users table will be updated with the subscription information via
the webhook. The customer will be redirected back to our customer portal where they will have
access to new features.
A customer can click “Manage Subscription” which will take them to the Stripe customer
portal, where they can either change the subscription level, change payment options, view
invoice history, cancel their subscription, or return to our customer portal. If they choose to
change their subscription our database will reflect that change as well as the features that are
available on our customer portal. A canceled subscription will still have access to the features
until the end of the billing cycle.
A customer may click “Schedule a Consultation” which will open the Calendly embedded
widget. This widget is tied to Sam’s email address and Calendly options such as availability, and
event type. After making a selection of meeting type, the user is directed to a calendar where
they can see available dates and times to meet with Sam. After confirming a timeslot, the user’s
email address is automatically filled in and they can enter any useful information about their
appointment. On completion, the database is updated and the appointment is added to both the
customer's and Sam’s calendars. The customer is sent a confirmation email where they can
either cancel or reschedule the appointment, both of these events are tracked in our database.
A cancellation will not count against the customer for the number of appointments booked.
The customer can also choose from a dropdown list of requests, the list is populated with
an array inside the customerPortal.ejs file. These requests vary depending on the level of
subscription. The user may enter details about their request and upload a supporting document
if they choose. After submitting the request the portal will be rendered to show the request on
the list of pending requests. After an admin completes the request it will be listed in a paginated
list of completed requests. As of 12/4, these requests are not constrained by any limits, a user
can place as many requests as they desire. As of 12/8, these requests are now limited by the
subscription level (view customization instructions for more info).

Admin Features
To register as an admin a user will need to get a code from our database in addition to
an email and password. The admin has access to all of the customers' submitted requests and
can filter to specify a particular user. Pending requests show on top of completed requests and
the filter applies to both. The admin can download the file that the user shared as part of their
request and add feedback before pressing the complete button. At this point, the request moves
from Pending to Completed for both the admin and the customer.
Database Diagram

The users table is the primary table containing everything related to the customer. Most columns
are self-explanatory but the subscription_duration_months is set to either 3 or 12 depending on
the subscription duration (quarter vs annual). This is used to determine the number of
consultation appointments that the user is allowed to make. As of 12/4/2023, the user is allowed
to book either 1 or 5 appointments per month depending on their subscription level. This is
currently hard-coded but could be changed to query a table with the respective values.

The consultations table includes a status column, the two expected values are ‘active’ or
‘canceled’. If the user decides to cancel an appointment via their confirmation email it will show
in the database as canceled and not count against them for the number of consultations they
have available.

Known bug: The Calendly widget will automatically populate the user's email address but this
field is not locked and the user may change their email address. If they enter an email address
that does not match, our database will store the appointment and it will show up on Sam's
calendar. However, this appointment will NOT count against the customer and they could
potentially schedule unlimited appointments. The Calendly support team told me there is no way
to lock that field at this time. It could be possible to create a custom widget but I believe that is a
project in itself. ~Kevin

Customization Instructions

Most Stripe related changes should be handled in the Stripe dashboard. Product
descriptions, feature lists, pricing tables, and pricing options. There are also customizable
subscription and email settings for various events at this link:
https://dashboard.stripe.com/settings/billing/automatic. Any changes made to the current pricing
table “prctbl_1OHJDWGuIql9Y6sUPIKC9kRh” will automatically be applied to the project.
Should you ever need to create a new pricing table you can follow the instructions and replace
the old pricing table ID with the new one on both the customer portal and the landing page EJS
files. On the creation of a new pricing table, you will need to update the helper function
getSubscriptionLevelFromPlanId with new values for each product.

The embedded Calendly widget is also customizable through the Calendly account.
Under settings, you can add, remove, or edit appointment event types. As of 12/6/2023, there
are two options on the Calendly widget Discovery Call and a 30-minute consultation. I believe all
options are available to all subscription levels, it may be possible to render a different widget but
that may require a secondary Calendly account.

The request type dropdown menu for customers is currently being populated by an array
near the bottom of the customerPortal.ejs file.

To change the number of consultations and requests allowed per subscription type you
can change the Heroku config vars. MONTHLY_CONSULTATIONS_BUSINESS: is set to 5 and
MONTHLY_CONSULTATIONS_STARTER: is set to 1 MONTHLY_REQUESTS_BUSINESS is
set to 12 and MONTHLY_REQUESTS_STARTER is set to 8.

For the custom payment option on our pricing table, instead of creating a billing session,
the user is prompted to call a placeholder phone number xxx-xxx-xxxx. This can be set up to an
email instead. After sending an email to Sam and working out what “Custom” means in this
case, a payment link will need to be created on the Stripe dashboard.
https://dashboard.stripe.com/payment-links/plink 1OKZBfGuIql9Y6sUWzGIlPua This link is for
a “Custom 1” plan at $500/3months. There is a Copy link button on this page that you can send
to a user manually via email. This is a placeholder Custom plan that is set up in our project,
however, if you want to create a more accurate custom plan will need to follow these
instructions.
1. Create a new product on the Stripe dashboard.
2. Create a new payment link and attach the new product to it.
3. Update the function getSubscriptionLevelFromPlanId in the server.js file.
4. Update the functions calculateAvailableRequests and calculateAvailableConsultations
again in the server.js file, there is an if block that will need the new product “name” given
in step 3.
5. Update the script in customerPortal.ejs file, there is a declared const subscriptionOptions
object that contains the request types that are available to that subscription level.
My recommendation for setting up custom types would be to create 2-5 different “custom” levels
all at the same time. This way instead of having to update code in multiple places and redeploy
you can simply share the payment link with them. I would give them names like “Custom 1-5”,
you must ensure that the string returned by getSubscriptionLevelFromPlanId matches the
calculateAvailable functions and the subscriptionOptions.

The Heroku deployment is currently set up to auto-deploy the main branch whenever a
change is pushed to that branch. It takes 30-90 seconds for Heroku to rebuild the project and
deploy it to the web. If you want to test changes locally I recommend using the GitHub desktop
app and VS Code. Once the app is set with access to the repository you can select the branch
you want to make changes to and press open in Visual Studio Code. In the PowerShell terminal
you should see the file location and to make sure your environment has the correct versions of
various dependencies type in npm i. To run the program type npm run dev, after a moment you
should be able to open http://localhost:8080/ in your web browser. If you want to test anything
related to Stripe locally you have to have the Stripe CLI and change the variable endpointSecret
= process.env.STRIPE_WEBHOOK_SECRET_LIVE to STRIPE_WEBHOOK_SECRET_TEST
. You can access the Stripe CLI with the Windows command prompt. Navigate to the directory
where the project is located ex (cd "Desktop\CSUMBstuff\CST 489 Capstone Project") then run
stripe listen --forward-to localhost:8080/webhook. This will allow the local instance to interact
with Stripe events. Testing the Calendly webhook must be done on a deployed internet version
like Heroku or using ngrok. Any changes you make to the server.js file will cause the site to
reboot, but changes to the routes .ejs files should reflect on a page refresh.

Updating Nodemailer Google Account

If you want to change the email address that sends the verification codes to users, you
will need to update the environment variables in the Heroku app settings and look for the
“Reveal Config Vars” button: https://dashboard.heroku.com/apps/cybersecurity0/settings

Once you click the button and expand the list of config vars, look for the environment
variable NODEMAILER_USER and update it with your preferred Google account username (the
text before the @), and for the password, update the environment variable
NODEMAILER_PASSWORD with the following password that you will obtain from here:
Go to your Google account settings https://myaccount.google.com/ and in the “search
Google account” search bar look for “App passwords”. Once there, type the name of the app in
the prompt and click Create. You should then see a popup box with a generated password,
make sure to store that password somewhere secure (leave the spaces in the password),
especially when copying and pasting it over to your NODEMAILER_PASSWORD environment
variable.

Google OAuth setup


The OAuth is currently using Roy’s personal Google account and is under “testing”
mode. This means the allowed user cap prior to app verification is 100 and is counted over the
entire lifetime of the app. Also, Token grant rates limit how quickly your application can get new
users. Your current per-day token grant rate limit is 10,000 grants per day. The per-day token
grant rate resets every day.

If you decide to have more control over the OAuth or decide to publish the app, you will
need to create your own OAuth credentials using your preferred Google account or the
company’s account. Follow these steps:
1. Create a Google Developer Project:

● Go to the Google Developers Console.


● Create a new project for your application.
● In your project, enable the "Google+ API" and create OAuth credentials.
● Then go to https://console.cloud.google.com/apis/credentials? To access the
credentials and add the following:
○ The authorized domains should be one for local development
http://localhost:8080 and another for the deployed app:
https://cybersecurity0-f5f3aa9877e5.herokuapp.com
○ The Authorized redirect URIs should be one for
http://localhost:8080/customerPortal/auth/google/callback and another for
https://cybersecurity0-f5f3aa9877e5.herokuapp.com/customerPortal/auth/
google/callback

2. Get Your OAuth Client ID and Client Secret:


● Once you've created OAuth credentials, in the same page
https://console.cloud.google.com/apis/credentials? You should see an “Additional
Information” section on the right side of the page where you can find your “Client
ID” and right under is the “Client Secrets” section where you find the “Client
secret”.
● Use those to update the GOOGLE_CLIENT_ID and
GOOGLE_CLIENT_SECRET environment variables in the heroku settings.
Google Cloud Storage bucket setup
The Google Cloud Storage (GCS) bucket is currently under a 90 day free trial that
started on 12/4/23 using Roy’s personal google account. You will need to create your own
bucket with GCS or consider other options like an Amazon S3 bucket.

However, if you choose to extend the GCS bucket, then creating a bucket involves the
following:

1. Go to the Google Cloud Console: Visit the Google Cloud Console.

2. Select/Create a Project: Create a new project or select an existing project where you
want to enable Google Cloud Storage.

3. Navigate to the IAM & Admin section: Click on the "IAM & Admin" menu from the
left-hand side.

4. Select Service Accounts: In the IAM & Admin section, select "Service Accounts" from the
menu.

5. Create a New Service Account: Click on the "Create Service Account" button at the top
of the page.

6. Enter Service Account Details:


Service account name: Provide a name for your service account.
Service account ID: An ID will be auto-generated based on the name.
Description: (Optional) Add a description for your service account.

7. Assign permissions like going to https://console.cloud.google.com/storage/browser? And


then select your bucket -> go to permissions tab -> enable public access to internet
And lastly assign your permissions like this for example (Click on +GRANT ACCESS to
configure/add permissions):
8. Then go to your Service Accounts menu and click on the account listed there:
https://console.cloud.google.com/iam-admin/serviceaccounts? Navigate to the "Keys"
tab and create a new key by clicking on the "Add Key" drop-down and select "Create
new key." Choose the key type as JSON and click the "Create" button. This will
download a JSON file containing your service account key. Keep this file secure as it
contains sensitive information.
9. LASTLY: open the JSON key on your computer and then proceed to update the following
environment variables in heroku settings using the values from your own JSON key
found in this format:
{
project_id: value to be added PROJECT_ID environment variable
private_key_id: value to be added to PRIVATE_KEY_ID env var,
private_key: value to be added to PRIVATE_KEY env var,
client_email: value to be added to CLIENT_EMAIL env var,
client_id: value to be added to CLIENT_ID env var,
auth_uri: value to be added to AUTH_URI env var,
token_uri: value to be added to TOKEN_URI env var,
auth_provider_x509_cert_url: value to be added to AUTH_PROVIDER env var,
client_x509_cert_url: value to be added to CLIENT env var,
universe_domain: value to be added to UNIVERSE_DOMAIN env var
}

You might also like