Chrono Capsule

Chrono Capsule Used AI

43 devlogs
53h 57m
•  Ship certified

An open-source platform to create encrypted, media-rich digital time capsules with scheduled unlocks. Send a message to the future, securely.

Timeline

Updated changelog with dependency upgrades.
Enhanced message sanitization by normalizing line endings and trimming whitespace.
Move toLocalISOString function outside the React component.
Add recipient name validation in capsule creation & username validation in registration on client side.

Update attachment

Sanitize the message provided in capsule creation.
Replace multiple whitespaces with single whitespace in name sanitization.
Added he library for escaping HTML for capsule message (escape while sending it, not before storing it in DB)

Update attachment

Fixed bug caused when unlock date is set, occurs because each time unlock date is set, timezone offset was removed, but the date was already in local time.
Updated changelog (also added the chores i.e. the dependency upgrades by dependabot to changelog)
Also added sanitization for recipient name and email in capsule creation.

Update attachment

A critical function was missing: To sanitize user inputs!
Sanitize user inputs (username, email, password) on backend.
I had to also revoke and create new gpg keys...

Up Next:
Sanitize inputs for capsule creation on backend, add validation on frontend...

Update attachment

Ship 3

1 payout of shell 162.0 shells

Puneet Gopinath

27 days ago

Puneet Gopinath Covers 6 devlogs

Disable submit button in forms when user clicks on it for better UX.
Fixed a small bug that creeped in recently to display email field (resend confirmation) to users who aren't logged in.
Pass setLoggedIn function to Header component for proper logout functionality.
Renamed state variable error2 to mediaError for better readability.
Styled loading text and added fade pulse animation to it (icon is from font awesome using react-icons npm package - added reference in about page, credits section)

Update attachment

Enhanced authentication flow by padding loggedIn state from App.jsx.
Switch back to use navigate method by react router instead of refreshing page for page redirects (as now loggedIn is governed by states).
Update verification form to conditionally display email field instead of using css hide.
Optimized view route by using .lean() on mongoose document to get plain object.
Added error handling and display errors in view capsules page with retry button.
Some other minor improvements.

Update attachment

Added create capsule button in view capsules page.
Redirect user after creating capsule to capsule view page.
Switch home page button on creating capsule to view capsule (Go to Dashboard).
Changed savedTheme to be a function instead of constant value for better sync

Update attachment

Created new Loading.jsx & CapsuleView.jsx.
User can now see all his created capsules in /dashboard/view
Renamed unlock route to view, and send capsules created by that user through that route (doesn't send message, media).
Lock view route to only logged in users.
Move CapsuleForm.jsx inside dashboard folder.
Fixed minor bugs.
Added script tag and loaded theme data from localStorage in index.html to avoid flash of other themed content.
Updated theme handling to set class name to html instead of body

Update attachment

Refactored the unlock capsule email too (Changed from a <div> to <table>).
Tested by sending the email to my gmail account.

Update attachment

Refactored the confirmation email template completely.
Changed from a <div> based layout to a <table> structure for appropriate rendering across clients.
Added a outer wrapper table and an inner wrapper table.
Reserved blank placeholder for the Chrono Capsule logo.
Tested using WPOven.

Update attachment

Ship 2

1 payout of shell 193.0 shells

Puneet Gopinath

about 1 month ago

Puneet Gopinath Covers 12 devlogs

Enabled trust proxy for proxies that are set in env variables.
Added verification check to prevent unverified users from creating capsules [BACKEND only].
Standardized error messages that are responses to the frontend.
Fixed a logical error in capsule controller that checks if unlock date is at least 50 minutes later.
Displayed the error message received from server in the capsule creation form.
Updated changelog & merged this pull request #14

Update attachment

Updated version in footer and package.json to v1.1.0-dev.
Added index to verification token to speed up lookups during verification.
Fixed: ensured sendConfirmation is awaited to catch email sending errors.
Merged pull request #7!!

Update attachment

Used react router's useNavigate function instead of window.location.href = "/";
Added aria-live attributes for better accessibility.
Added abort signal to verification request for better cleanup on unmount.
Added express-rate-limit to limit resend confirmation to only 5 requests per IP per hour.
Updated changelog

Update attachment

Added live countdown message for re-send verification cooldown
Enhance styles in verify page
Fixed bug, reset error to null after verification email is sent so that the notice is displayed.
Update console log messages at backend for sending confirmation email.

Update attachment

Added resend confirmation functionality as a button on the verify page with email as input.
Fixed a bug, variable name mismatch b/w ejs template and provided variable while rendering.
Added a feature that the email input field only displays if user isn't logged in. If they are, it automatically takes the token set in the localStorage and sends it to server as an Authorization header.
Added cooldown of 30 seconds to click the resend verification button again(although I haven't yet added a live countdown of 30 seconds yet)

Update attachment

Released v1.0.1:
Introduced new environment variable SMTP_SENDER to define the visible from address in an email.
SMTP Sender mismatch: Resolved email delivery failure due to a different SMTP Sender rather than the SMTP User.

Now emails work! Previously, as I had no domain, I couldn't send emails.

Update attachment

Added new EJS templates for email confirmation: confirm.ejs & confirm.txt.ejs
Renamed email.ejs & email.txt.ejs to capsule.ejs & capsule.txt.ejs
Implemented to mail the confirmation link to the user, and also added website link in each email.

A good news: I've got a domain at namecheap today: puneetg.me, and I've set up a subdomain for chrono-capsule: https://capsule.puneetg.me/
THIS IS MY FIRST DOMAIN

Update attachment

Added Verify page on frontend (React) to verify email of newly registered users.
Added a loading spinner
Also validation to the token on frontend and backend, on backend to avoid fetching from database, imagine the token is not even valid, then why mess with database?

Update attachment

Added user verification functionality.
Added fields (verified, verification.token, verification.expiresAt) to user schema
Tested verification using postman (attached)

Next: Send emails containing link with token for verifying email

Update attachment

Released v1.0.0
Updated changelog

What's up next?
- Add email verification (to check if the entered email is actually the user's own email)
- Add a dashboard.
- Integrate to calender
- Email confirmation to Sender (mentioning that the capsule has been unlocked)

Update attachment

Released v1.0.0-beta

Bugs fixed

Import home.css in Home react component, otherwise it doesn't show up in production build
Fix bug in RegExp of route handling for production built files
Added a missing await keyword before ejs.renderFile to return string instead of a Promise
Change navigation method to window.location.href after login, this helps update the links in the header of the site.
Improve debug logging
UX enhancement: changed capsule unlock scheduler from every hour to every 10 minutes
Fix raw text EJS template: replace \n (ejs renders it as text) with actual new lines

Update attachment

Shipped the project.
I'm crazy, I edited the changelog and commited but forgot to push to github before tagging a new release of v1.0.0-alpha
Also, I didn't only test sending of emails before releasing that version, seems exactly it failed. I forgot an await in the ejs template rendered.
Also implemented static files into express from the build folder of vite. I also forgot importing home.css file in home component, which took me time to understand as I'm new to react (I was like - importing a css file into javascript?)
The attached image shows the author section in about page

Update attachment

Ship 1

1 payout of shell 372.0 shells

Puneet Gopinath

about 1 month ago

Puneet Gopinath Covers 21 devlogs

Successful completion of v1.0.0-alpha.

Added Home Page, placeholder for terms in Terms page and similarly in Privacy page
Removed action and method fields in html form that prevented full control to onSubmit function
Whenever an error due to invalid data provided by the user, scroll to top.
Removed bug due to difference in seconds
Added create capsule & logout button in the header
Removed other minor bugs and updated README, CHANGELOG

Update attachment

Added EJS templates for the email html and text content.
Added a div element for displaying errors instead of showing errors using alert function.

I wanted to show the about page, so I'm writing this devlog after just few minor changes

Update attachment

Added Register.jsx to allow users to register their account
Prevent access to /create when not logged in (NotLoggedIn.jsx)
Hide login and register forms when already logged in (LoggedIn.jsx)
Added about page to display details about project and author (text written by Copilot)

Update attachment

Update file headers to include copyright, filename and license information

Update attachment

Guys, A small note, I'm still learning React, so if you think I've consumed more time than expected in frontend, keep this in mind.

  • Built Login page, also included password toggle feature
  • Switched to sending form data as json, as backend doesn't support form data
  • Fixed bugs arising due to adding timezone offset in a local date itself
  • Added 1 Hour chip to directly set unlock date as an hour later.
  • Created a function to format local time in ISO[toLocalISOString()] after realizing that toISOString gives UTC time.
  • Fixed a tiny logic bug
Update attachment
  • Implemented unlock date validation, on the frontend, we validate that it's at least 1 hour in the future. But on the backend, we validate if it's 50 minutes in future at the time of submission of the form.
  • Replaced file uploads with dynamic media link inputs (will support file uploads in future)
  • Fixed issue of calender icon not showing up on dark mode (input type=datetime-local) by using color-scheme property of css
  • Theme preferance is now stored in localStorage
  • Marked all fields required except media links and encryption.
  • Form submit bug squashed.
Update attachment

Introduced dark theme, used CSS variable-based color system
Made dark theme set by default
Simple toggle using ☀ and ☾ unicode icons

What's next:
- Unlock date validation
- Persist theme color in localStorage

Update attachment
  • Added checkbox to choose to encrypt the contents or not. Used flexbox alignment to center the text and checkbox
  • Added optional mobile tweaks using @media (max-width: 480px) to set flex-direction to column
  • Tried custom checkbox, but didn't work. Might add later.

What's next:
- Dark theme
- Unlock Date validation (must be at least 1 hour from now)

Update attachment

Added a header component, used react router's Link component to direct users to other webpages of chrono capsule website, added a fade-out style to the Reset button (fades out in 0.2s)

Update attachment

FRONTEND:
Added unlock date suggestions (1 week, 1 month, 6 months, 1 year), clicking on them calculates the future date and populates the input.
Added smooth styling, a reset selection button (or a chip) when a suggestion is selected
Used 999px as border radius to create smooth pill shaped buttons
Add a footer to the website (Header is still pending 🤣)

BACKEND:
Limited username to a min of 3 & max of 30 characters, password to a min of 8 & max of 128
Limited user & recipient email to 254 characters (max length as per RFC 5321😁)

Update attachment

Added CapsuleForm.jsx as the interface for creating time capsules
Integrated useState method from React module to display message character count
Implemented live character count with a 5000-character limit
Styled the form with modern light theme (dark theme coming soon)
Resolved vite import path issue for index.jsx by setting root in vite.config.js

Update attachment

Added vite as npm dev dependency, setup files for frontend (index.html, index.css, index.jsx, App.jsx)
Sketched roadmap for v0.2.0-alpha, beta and final release

Update attachment

Added health route at /health to verify status of the server, wrote Changelog
Message character limit capped at 5000
Released the first versioned build of chrono-capsule: v0.1.0
Hurray!!!
Go check it out for yourself: https://github.com/PuneetGopinath/chrono-capsule/releases/tag/v0.1.0

Update attachment

Used WPOven to test emails, attached sample email received after a capsule has been unlocked.

Update attachment

Added decryption for both message and media files before sending email
Personalized email content with recipient name and upgraded the HTML template
Fixed bug of not saving media files to database
Tested capsule creation with media files (attached - done using postman) and tested sending of email (using WPOven)

Logged a major milestone: full cycle from capsule creation => unlock => delivery now works end-to-end!

Update attachment

Collected recipient name for personalised greetings, switched media to an array of media files instead of a single media file, added node-cron to auto-unlock capsules on schedule, added nodemailer to send emails after capsules unlock, updated user schema to validate email before storage.

At the end of the day, learnt a lot of new stuff

Update attachment

Tested capsules/create route using postman, added functionality to check if email is already used before user registration.

Update attachment

Added debug logging, tested auth routes using postman

Update attachment

Added user authentication, capsule management routes, encryption support of content present inside capsule using crypto module of nodejs (for password storage of a particular user, we're using bcryptjs)

Update attachment

Added connection to MongoDB database, express for handling backend of the website, models for storage of capsules and utilities.

Update attachment

Added README.md and made a mental map of all features to design.

Update attachment