Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate to TS with Lit Web Components #152

Conversation

dchege711
Copy link
Owner

@dchege711 dchege711 commented Jun 8, 2024

Rewrite the application using Typescript for more type safety.

Additionally, use Lit Web Components to render dynamic parts of the application.

See 1 for deployment.

The app is crashing and the tests are failing though.
Fixes the "Could not find metadata document" error in tests.
This is not the proper fix as there may be data loss. Revisit this
before checking in.

```log
/Users/dchege711/study_buddy/node_modules/mongoose/lib/model.js:486
    parallelSave = new ParallelSaveError(this);
                   ^

ParallelSaveError: Can't save() the same doc multiple times in parallel. Document: 64a09467f8e97e57a99a49fb
    at Model.save (/Users/dchege711/study_buddy/node_modules/mongoose/lib/model.js:486:20)
    at updateMetadataWithCardDetails (/Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:545:24)
    at Object.<anonymous> (/Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:171:62)
    at step (/Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:56:23)
    at Object.next (/Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:37:53)
    at /Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:31:71
    at new Promise (<anonymous>)
    at __awaiter (/Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:27:12)
    at /Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:168:70
    at Array.forEach (<anonymous>)
    at Object.<anonymous> (/Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:168:32)
    at step (/Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:56:23)
    at Object.next (/Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:37:53)
    at fulfilled (/Users/dchege711/study_buddy/dist/models/MetadataMongoDB.js:28:58)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
```
Much better stack traces, e.g.:

```log
TypeError: Cannot read properties of undefined (reading 'sample_card')
      at /Users/dchege711/study_buddy/src/models/MetadataMongoDB.ts:149:55
      at Array.forEach (<anonymous>)
      at _loop_1 (src/models/MetadataMongoDB.ts:147:40)
      at Object.<anonymous> (src/models/MetadataMongoDB.ts:240:25)
      at step (src/models/MetadataMongoDB.ts:56:23)
      at Object.next (src/models/MetadataMongoDB.ts:37:53)
      at fulfilled (src/models/MetadataMongoDB.ts:28:58)
      at processTicksAndRejections (node:internal/process/task_queues:95:5)
```
* MetadataMongoDB.create fails if the metadata already exists.
* MetadataMongoDB.update calls save() on the document.
* MetadataMongoDB.updatePublicUserMetadata accounts for the first run
  when the array is empty.
For some reason, I couldn't get [1] to work, hence copy-webpack-plugin.

[1]: https://webpack.js.org/guides/asset-modules/
```log
MongoError: query requires text score metadata, but it is not available
    at Connection.<anonymous> (/Users/dchege711/study_buddy/node_modules/mongoose/node_modules/mongodb/lib/core/connection/pool.js:453:61)
    at Connection.emit (node:events:513:28)
    at Connection.emit (node:domain:489:12)
    at processMessage (/Users/dchege711/study_buddy/node_modules/mongoose/node_modules/mongodb/lib/core/connection/connection.js:456:10)
    at Socket.<anonymous> (/Users/dchege711/study_buddy/node_modules/mongoose/node_modules/mongodb/lib/core/connection/connection.js:625:15)
    at Socket.emit (node:events:513:28)
    at Socket.emit (node:domain:489:12)
    at addChunk (node:internal/streams/readable:324:12)
    at readableAddChunk (node:internal/streams/readable:297:9)
    at Socket.Readable.push (node:internal/streams/readable:234:10)
    at TCP.onStreamRead (node:internal/stream_base_commons:190:23) {
  ok: 0,
  code: 40218,
  codeName: 'Location40218'
}
```

[1] notes that textScore is only available when used in conjunction with
a $text query.

[1]: https://www.mongodb.com/docs/manual/reference/operator/aggregation/meta/
Configure web-pack to provide various files.
These two resources are easier to consume on the browser-side.
Couldn't get src/public/src/lib/AVLTree.d.ts and
src/public/src/lib/AVLTree.js to work on the browser, so using the node
version at [1] instead.

[1]: https://github.com/w8r/avl
The Dockerfile.render was automagically populated by the Heroku migrator. Let's first use
a familiar route.
The project builds fast enough. For now, use the simpler
complete rebuild to minimize headache.
[1] failed with:

```log
> [email protected] build:client
> pushd src/public && npm run build && popd

sh: 1: pushd: not found
Error: Process completed with exit code 127.
```

This is a speculative fix.

[1]: https://github.com/dchege711/study_buddy/actions/runs/9431492588/job/25980205770?pr=152
Identified by CodeQL. The idea is that routes that carry out expensive operations, e.g.,
hitting a database, are susceptible to DDOS attacks. [1] provides a convenient approach
to rate-limiting per IP.

[1]: https://express-rate-limit.mintlify.app/quickstart/usage
I get a "Error: CSRF token missing" when trying to log in.
src/server.ts Fixed Show fixed Hide fixed
src/server.ts Fixed Show fixed Hide fixed
Comment on lines +57 to +68
app.use(session({
secret: [config.STUDY_BUDDY_SESSION_SECRET_1],
secure: true,
httpOnly: true,
resave: false,
name: "c13u-study-buddy",
store: config.IS_DEV ? session.MemoryStore() : MongoStore.create({
mongoUrl: config.MONGO_URI,
touchAfter: 24 * 3600
}),
saveUninitialized: true
}));

Check warning

Code scanning / CodeQL

Clear text transmission of sensitive cookie Medium

Sensitive cookie sent without enforcing SSL encryption.
Comment on lines +57 to +68
app.use(session({
secret: [config.STUDY_BUDDY_SESSION_SECRET_1],
secure: true,
httpOnly: true,
resave: false,
name: "c13u-study-buddy",
store: config.IS_DEV ? session.MemoryStore() : MongoStore.create({
mongoUrl: config.MONGO_URI,
touchAfter: 24 * 3600
}),
saveUninitialized: true
}));

Check failure

Code scanning / CodeQL

Missing CSRF middleware High

This cookie middleware is serving a
request handler
without CSRF protection.
This cookie middleware is serving a
request handler
without CSRF protection.
This cookie middleware is serving a
request handler
without CSRF protection.
This cookie middleware is serving a
request handler
without CSRF protection.
This cookie middleware is serving a
request handler
without CSRF protection.
This cookie middleware is serving a
request handler
without CSRF protection.
This cookie middleware is serving a
request handler
without CSRF protection.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant