-
Notifications
You must be signed in to change notification settings - Fork 13
Initial Task List and Scope
Alex Romanova edited this page Feb 13, 2023
·
48 revisions
The following is a high-level list of tasks that need to be considered and implemented at some point (they are not prioritized). The goal of this list is to help define the scope of the tasks, technologies, and patterns we need to use.
This list needs to be turned into Issues and, very quickly, this list should become obsolete.
Category | Interested | Assigned |
---|---|---|
Front end | Eakam, Mario, Tymyr | Eakam |
Back end | Stef, Taimoor, Eakam, Tymur | Taimoor |
Data | Taimoor, Chen-Yuan | Chen-Yuan |
Authentication | Stefan Frunza | Stefan |
Notifications | Taimoor | Taimoor |
DNS | Alex, Won | Won |
Certificates | Denes, Won | Denes |
Development | Alex, Won | Won |
Testing | Stef, Eakam | Eakam |
Deployment | Stef | Stef, Dave |
Documentation | Alex | Alex |
Queue | Denes |
Category | Due | Challenge | Status |
---|---|---|---|
Certificates | Milestone 0.2 | Should be able to issue (staging) a cert with manual control and no DNS verification | DONE |
Authentication | Milestone 0.2 | Setting up docker container for test SAML idp, see what I can do with SAMLIFY. | |
Notifications | Milestone 0.2 | Ensure that we are able to successfully send test notifications | |
Data | Milestone 0.2 | Have seeding work for tables other than User table. |
- We'll need some page designs very quickly. Start looking at existing DNS/Cert UIs (e.g., AWS, CloudFlare, Azure, Google Cloud, Namecheap, etc). How do they solve this UX? Learn from them, and let's not waste time inventing new UI.
- Use the Remix Blue Stack as a basis for our initial setup. It does most of what we need, and we'll swap out or remove some pieces later on
- Setup Chakra UI with Remix. See also the Chakra UI Remix Example
- Use ChakraUI for all our components vs. creating our own
- Use
colorScheme='red'
for ChakraUI components to match Seneca's red colour theme, see https://chakra-ui.com/docs/components/button/usage#usage - Landing page with a way to login
- All other pages should require a user to be authenticated
- User Dashboard page with a way to create or manage subdomains and certificates
- User can create new subdomains (A, AAAA, CNAME)
- User can view existing subdomains
- User can update existing subdomains
- User can delete existing subdomains
- User can renew a subdomain for an additional period of time (e.g., add another 6 months)
- User can create a wildcard certificate
- User can view wildcard certificate and private key
- User can get instructions on how to use the certificate
- User can revoke wildcard certificate
- User can renew wildcard certificate
- Admin Dashboard with overall stats (e.g., how many users, subdomains, certs) and a way to query/filter/view/modify all user data
- Include link to Seneca's Acceptable Use Policy (e.g., can't use submdomains/certs for commercial use, etc)
- Consider swapping Remix's Express server for Satellite. This may require some tweaks to Satellite to make it usable outside of Telescope. We might also decide to port a bunch of best-practices from Satellite over to the
server.ts
code used in Remix instead (i.e., to not bother pulling in unnecessary dependencies like elastic, redis, etc). - Use Satellite's logger (Pino)
- Use server-side cookie based sessions to simplify scaling in production. See https://remix.run/docs/en/v1/utils/sessions
- Include healthcheck route, which can be used in Docker to figure out if the server is OK
- Figure out the best solution to doing background tasks. The system needs to send notifications and perform other background tasks like removing domains/certs after they expire. This shouldn't happen on the main thread. Many systems that do this (Telescope for example) use a queue and workers based on BullMQ and Redis.
- Create an initial Prisma schema for MySQL. See also https://www.prisma.io/docs/concepts/components/prisma-schema
- User data from SAML response (username, email, name, etc)
- Subdomains for a user (username, subdomain, description, ports list, course, date created, when it expires)
- Certificates for a user (username, subject, certificate in PEM format, private key in PEM format encrypted, when it's valid from/to)
- Figure out how to use MySQL via docker compose in development
- Figure out the best way to encrypt private keys for secure storage in the database
- Domain records should include a Description of how it is being used, Port numbers, Course code (if any)
- Use Samlify with Remix to do SAML2 auth. See https://github.com/christopherpickering/remix-saml-authentication and https://github.com/remix-run/examples/pull/130
- Figure out solution for user vs. admin (possibly using extra security group info in SAML response from Seneca, or maybe via extra column in users database table).
- Write code to properly format a username for use in DNS. For example: remove a
.
. Write tests for this. - We need to be able to configure our backend to talk to Seneca's SSO IdP. Learn from how we do it in Telescope.
- Use nodemailer to send email notifications to users. For example, when a domain or certificate is going to expire and should be renewed.
- Configure nodemailer to use an OAuth-based email account on staging and production
- Enforce a configurable (i.e., env var) limit on the number of subdomains each user can create. Write tests to make sure this works.
- Decide if we should detect and ban "bad words" in domain names (e.g., use something like https://github.com/web-mech/badwords)
- Configure AWS JS SDK v3 to use our IAM User's credentials and Region in dev/staging/production
- Configure the Route53 client to use our Hosted Zone ID (i.e., get it from the environment)
- Create a "dns" module that we can use on the server-side (e.g.,
app/lib/dns.server.ts
or something) to work with DNS records in various parts of the app. Specifically, it will need to:- Use the ChangeResourceRecordSetsCommand to create, update, or delete resource records in the hosted zone.
- Write unit tests for creating, updating, and deleting resource records against a mock route53 container
- Use the GetChangeCommand to determine when DNS records have been propagated (i.e., are ready to be used vs just requested).
- Write unit test for querying the state of a record with AWS against a mock route53 container
- Domains should expire after a configurable (i.e., env var) amount of time. Default to 6 months.
- Send an email before a domain is going to expire so users can log in and renew. Amount of time should be configurable (i.e., env var)
- Deal with, and write tests for, various rate limiting issues with Route53
- Provide detailed info page showing how to use certificate we generate (i.e., DNS Challenge)
- Provide detailed info page showing how to setup an HTTP Challenge to auto-renew a certificate we don't generate, but uses one of our domains
- Provide a way to generate a wildcard cert for the user's top-level subdomain. The DNS for the subdomain must be active in Route53 first
- Provide a way to get the existing cert + private key after it has been created (e.g., 1 month later when they have forgotten)
- Provide a way to renew an existing cert
- Provide a way to revoke an existing cert
- Send notifications to users before certs will expire. Time before expiry should be configurable (i.e., env var)
- Deal with, and write tests for, various rate limiting issues with Let's Encrypt
- Adopt an "it should be simple to get this app running locally" philosophy. When we make choices, make sure that we don't add complexity that's hard to manage. Automate and simplify.
- Use docker compose to create the necessary services locally and in CI/CD
- Configure MySQL container
- Configure Moto for mock Route53 container. See http://docs.getmoto.org/en/latest/docs/server_mode.html#run-using-docker
- Configure a mock SAML IdP container. We could follow the same strategy as Telescope: use the test-saml-idp container, configure it, and specify users. Or there might be a better solution?
- Configure mock SMTP container for testing sending email messages. Could use https://github.com/rnwood/smtp4dev or https://greenmail-mail-test.github.io/greenmail/, etc.
- Configure mock Let's Encrypt container for testing certs locally and in CI/CD. We can use https://github.com/letsencrypt/pebble
- Use Husky git hooks to automatically run prettier and enforce our formatting on every commit. See how we do it in Telescope
- Configure VSCode settings for prettier, eslint, extensions, etc. Build on what we do in Telescope
- Adopt an aggressive testing philosophy. When you review new code, always ask "how will we test this?" and "where are the tests?" If we don't have tests, we can't trust the code, and should be skeptical. NOTE: tests don't always need to happen first or at the same time; but there needs to be a plan to add them.
- Use Jest for unit testing. See also https://sergiodxa.com/articles/test-remix-loaders-and-actions for Remix specific bits on loaders, etc.
- Use Playwright for e2e testing
- Use GitHub Actions for CI to check eslint, prettier, unit tests, e2e tests, etc.
- Add test coverage info so we know how we're doing
- Adopt a deploy-first mentality: if it's hard to deploy, we won't do it, therefore we won't be able to test it for real. Focus on making things easy to deploy.
- Dockerize the Remix Web App/Server
- Use GitHub Actions to publish image on every push to
main
andtag
. Could use CDOT's private registry or some public one? - Use GitHub Actions for CD to deploy to staging server
- Use docker swarm for staging and production deployments
- Use webhooks (e.g., https://github.com/adnanh/webhook) to trigger updates on staging and production from CD
- Explore use of SolarWinds APM for integration with Seneca monitoring infrastructure. See https://github.com/solarwindscloud/solarwinds-bindings-node. Need to confirm with ITS if they want.
- Create top-level, static web page for senecastudent.ca that explains what all subdomains on the server are for, give contact info, etc. Could redirect to this page.
- Figure out a name for the service (i.e., {name}.senecacollege.ca prod and {name}-dev.senecacollege.ca staging). Starchart is our technology name, but we need a product/service name that the Seneca community will use.
- Deal with log rotation so we don't fill-up the staging/prod disk.
- Don't log more than necessary in production (e.g., errors)
- Figure out how we're going to do HTTPS in staging/production: does Seneca handle this, or do we need to?
- Adopt a "docs matter" philosophy. We want this project to succeed long term, even when all of the current devs have moved on. To do that, we have to capture our knowledge in docs. When people make big changes, always ask "do we need to update or add docs for this?" and "where are the docs?" Docs can come later vs. at the same time, but it needs to be included in our planning.
- Start to organize our documentation in the Wiki so it's going to be easy for new devs to join us later on (proper links between docs, hierarchy)
- Create a
CONTRIBUTING.md
to help new devs get involved. Keep it updated - Create and maintain our
README.md
to help people understand what the project is, now to use it, etc. - Create docs for deploying and maintaining the servers in staging and production