├── .nvmrc ├── apps ├── client │ ├── src │ │ ├── boot │ │ │ ├── .gitkeep │ │ │ ├── stripe.client.ts │ │ │ ├── syncedstore.client.ts │ │ │ ├── array-at-polyfill.client.ts │ │ │ ├── sodium.universal.ts │ │ │ ├── http-headers │ │ │ │ ├── disable-cache.universal.ts │ │ │ │ ├── x-frame-options.universal.ts │ │ │ │ └── referrer-policy.universal.ts │ │ │ ├── logger.client.ts │ │ │ ├── helpers.universal.ts │ │ │ ├── prosemirror.client.ts │ │ │ └── vue.universal.ts │ │ ├── pages │ │ │ ├── pages │ │ │ │ ├── Pages.vue │ │ │ │ └── Group.vue │ │ │ └── home │ │ │ │ └── Help │ │ │ │ └── Pages │ │ │ │ ├── SubscriptionExpiration.vue │ │ │ │ └── Roadmap.vue │ │ ├── i18n │ │ │ ├── index.ts │ │ │ └── en-US │ │ │ │ └── index.ts │ │ ├── assets │ │ │ ├── main.mp4 │ │ │ ├── notes.mp4 │ │ │ ├── collab.mp4 │ │ │ ├── platforms │ │ │ │ ├── mac.webp │ │ │ │ ├── linux.webp │ │ │ │ └── windows.webp │ │ │ ├── badges │ │ │ │ └── google-play.webp │ │ │ └── white-logo-outline.webp │ │ ├── css │ │ │ └── fonts │ │ │ │ └── Inter │ │ │ │ ├── Inter-Black.ttf │ │ │ │ ├── Inter-Bold.ttf │ │ │ │ ├── Inter-Light.ttf │ │ │ │ ├── Inter-Thin.ttf │ │ │ │ ├── Inter-Medium.ttf │ │ │ │ ├── Inter-Regular.ttf │ │ │ │ ├── Inter-SemiBold.ttf │ │ │ │ ├── Inter-ExtraBold.ttf │ │ │ │ └── Inter-ExtraLight.ttf │ │ ├── layouts │ │ │ └── PagesLayout │ │ │ │ ├── MainContent │ │ │ │ └── DisplayPage │ │ │ │ │ └── DisplayScreens │ │ │ │ │ ├── DisplayNonExistentScreen.vue │ │ │ │ │ ├── DisplayRejectedScreen.vue │ │ │ │ │ ├── DisplayErrorScreen.vue │ │ │ │ │ ├── DisplayNonFreePageScreen.vue │ │ │ │ │ ├── DisplayProPlanRequiredScreen.vue │ │ │ │ │ └── DisplayWorld │ │ │ │ │ └── DisplayNote │ │ │ │ │ └── NoteSection │ │ │ │ │ └── NoteContainerSection │ │ │ │ │ └── NoteContainerSection.vue │ │ │ │ └── MainToolbar │ │ │ │ └── Notifications │ │ │ │ ├── NotificationsBtn.vue │ │ │ │ └── NotificationsBadge.vue │ │ ├── code │ │ │ ├── internals.ts │ │ │ ├── areas │ │ │ │ ├── api-interface │ │ │ │ │ ├── pages │ │ │ │ │ │ ├── deletion │ │ │ │ │ │ │ ├── delete.ts │ │ │ │ │ │ │ ├── restore.ts │ │ │ │ │ │ │ └── delete-permanently.ts │ │ │ │ │ │ ├── snapshots │ │ │ │ │ │ │ └── delete.ts │ │ │ │ │ │ ├── bump.ts │ │ │ │ │ │ └── backlinks │ │ │ │ │ │ │ └── create.ts │ │ │ │ │ ├── groups │ │ │ │ │ │ ├── deletion │ │ │ │ │ │ │ ├── delete.ts │ │ │ │ │ │ │ ├── restore.ts │ │ │ │ │ │ │ └── delete-permanently.ts │ │ │ │ │ │ └── privacy │ │ │ │ │ │ │ └── make-public.ts │ │ │ │ │ └── users │ │ │ │ │ │ ├── delete-account.ts │ │ │ │ │ │ ├── add-favorite-pages.ts │ │ │ │ │ │ └── remove-favorite-pages.ts │ │ │ │ └── tiptap │ │ │ │ │ └── image-resize │ │ │ │ │ └── extension.ts │ │ │ ├── cookies.ts │ │ │ ├── utils │ │ │ │ ├── math.ts │ │ │ │ └── zxcvbn.ts │ │ │ └── pages │ │ │ │ ├── page │ │ │ │ ├── notes │ │ │ │ │ └── date.ts │ │ │ │ └── elems │ │ │ │ │ └── elems.ts │ │ │ │ ├── composables │ │ │ │ ├── use-key-state-tracking.ts │ │ │ │ ├── use-touchscreen-pointer-capture-release.ts │ │ │ │ ├── use-middle-click-paste-prevention.ts │ │ │ │ └── use-window-resize-listener.ts │ │ │ │ └── computed │ │ │ │ └── page-group-id.ts │ │ ├── components │ │ │ ├── ResponsiveContainer.vue │ │ │ ├── Gap.vue │ │ │ ├── InlineGap.vue │ │ │ ├── ViewportLoadingOverlay.vue │ │ │ ├── CustomInfiniteScroll.vue │ │ │ ├── PassthroughComponent.vue │ │ │ ├── TabBtn.vue │ │ │ ├── Checkbox.vue │ │ │ └── Radio.vue │ │ ├── stores │ │ │ ├── store-flag.d.ts │ │ │ ├── app.ts │ │ │ ├── page-selection.ts │ │ │ ├── auth.ts │ │ │ ├── index.ts │ │ │ └── pages.ts │ │ ├── vue-props.d.ts │ │ └── shims-vue.d.ts │ ├── src-capacitor │ │ ├── .gitignore │ │ ├── android │ │ │ ├── fastlane │ │ │ │ ├── .gitignore │ │ │ │ ├── metadata │ │ │ │ │ └── android │ │ │ │ │ │ ├── id │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ └── full_description.txt │ │ │ │ │ │ ├── th │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ └── full_description.txt │ │ │ │ │ │ ├── de-DE │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ └── full_description.txt │ │ │ │ │ │ ├── es-419 │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ └── full_description.txt │ │ │ │ │ │ ├── es-ES │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ └── full_description.txt │ │ │ │ │ │ ├── fr-FR │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ └── full_description.txt │ │ │ │ │ │ ├── it-IT │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ └── full_description.txt │ │ │ │ │ │ ├── ja-JP │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ └── full_description.txt │ │ │ │ │ │ ├── pt-BR │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ └── full_description.txt │ │ │ │ │ │ ├── zh-CN │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ └── full_description.txt │ │ │ │ │ │ └── en-US │ │ │ │ │ │ ├── title.txt │ │ │ │ │ │ ├── video.txt │ │ │ │ │ │ ├── short_description.txt │ │ │ │ │ │ ├── full_description.txt │ │ │ │ │ │ ├── images │ │ │ │ │ │ ├── icon.png │ │ │ │ │ │ ├── featureGraphic.png │ │ │ │ │ │ ├── phoneScreenshots │ │ │ │ │ │ │ ├── 1_en-US.png │ │ │ │ │ │ │ ├── 2_en-US.png │ │ │ │ │ │ │ ├── 3_en-US.png │ │ │ │ │ │ │ ├── 4_en-US.png │ │ │ │ │ │ │ ├── 5_en-US.png │ │ │ │ │ │ │ ├── 6_en-US.png │ │ │ │ │ │ │ ├── 7_en-US.png │ │ │ │ │ │ │ └── 8_en-US.png │ │ │ │ │ │ ├── sevenInchScreenshots │ │ │ │ │ │ │ ├── 1_en-US.png │ │ │ │ │ │ │ ├── 2_en-US.png │ │ │ │ │ │ │ ├── 3_en-US.png │ │ │ │ │ │ │ ├── 4_en-US.png │ │ │ │ │ │ │ ├── 5_en-US.png │ │ │ │ │ │ │ ├── 6_en-US.png │ │ │ │ │ │ │ ├── 7_en-US.png │ │ │ │ │ │ │ └── 8_en-US.png │ │ │ │ │ │ └── tenInchScreenshots │ │ │ │ │ │ │ ├── 1_en-US.png │ │ │ │ │ │ │ ├── 2_en-US.png │ │ │ │ │ │ │ ├── 3_en-US.png │ │ │ │ │ │ │ ├── 4_en-US.png │ │ │ │ │ │ │ ├── 5_en-US.png │ │ │ │ │ │ │ ├── 6_en-US.png │ │ │ │ │ │ │ ├── 7_en-US.png │ │ │ │ │ │ │ └── 8_en-US.png │ │ │ │ │ │ └── changelogs │ │ │ │ │ │ └── 62.txt │ │ │ │ └── Appfile │ │ │ ├── app │ │ │ │ ├── .gitignore │ │ │ │ └── src │ │ │ │ │ ├── main │ │ │ │ │ ├── res │ │ │ │ │ │ ├── drawable │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-land-hdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-land-mdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-hdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-mdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── values │ │ │ │ │ │ │ ├── ic_launcher_background.xml │ │ │ │ │ │ │ └── strings.xml │ │ │ │ │ │ ├── drawable-land-xhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-land-xxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-xhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-xxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ │ ├── ic_launcher.png │ │ │ │ │ │ │ ├── ic_launcher_round.png │ │ │ │ │ │ │ └── ic_launcher_foreground.png │ │ │ │ │ │ ├── drawable-land-xxxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── drawable-port-xxxhdpi │ │ │ │ │ │ │ └── splash.png │ │ │ │ │ │ ├── xml │ │ │ │ │ │ │ ├── config.xml │ │ │ │ │ │ │ └── file_paths.xml │ │ │ │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ │ │ │ ├── ic_launcher.xml │ │ │ │ │ │ │ └── ic_launcher_round.xml │ │ │ │ │ │ └── layout │ │ │ │ │ │ │ └── activity_main.xml │ │ │ │ │ ├── java │ │ │ │ │ │ └── app │ │ │ │ │ │ │ └── deepnotes │ │ │ │ │ │ │ └── MainActivity.java │ │ │ │ │ └── assets │ │ │ │ │ │ └── capacitor.plugins.json │ │ │ │ │ └── test │ │ │ │ │ └── java │ │ │ │ │ └── com │ │ │ │ │ └── getcapacitor │ │ │ │ │ └── myapp │ │ │ │ │ └── ExampleUnitTest.java │ │ │ ├── Gemfile │ │ │ ├── gradle │ │ │ │ └── wrapper │ │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── settings.gradle │ │ │ └── variables.gradle │ │ ├── ios │ │ │ ├── App │ │ │ │ ├── fastlane │ │ │ │ │ ├── metadata │ │ │ │ │ │ ├── en-US │ │ │ │ │ │ │ ├── marketing_url.txt │ │ │ │ │ │ │ ├── promotional_text.txt │ │ │ │ │ │ │ ├── apple_tv_privacy_policy.txt │ │ │ │ │ │ │ ├── name.txt │ │ │ │ │ │ │ ├── subtitle.txt │ │ │ │ │ │ │ ├── support_url.txt │ │ │ │ │ │ │ ├── privacy_url.txt │ │ │ │ │ │ │ ├── keywords.txt │ │ │ │ │ │ │ ├── release_notes.txt │ │ │ │ │ │ │ └── description.txt │ │ │ │ │ │ ├── primary_first_sub_category.txt │ │ │ │ │ │ ├── primary_second_sub_category.txt │ │ │ │ │ │ ├── secondary_category.txt │ │ │ │ │ │ ├── primary_category.txt │ │ │ │ │ │ ├── secondary_first_sub_category.txt │ │ │ │ │ │ ├── secondary_second_sub_category.txt │ │ │ │ │ │ ├── copyright.txt │ │ │ │ │ │ └── review_information │ │ │ │ │ │ │ ├── first_name.txt │ │ │ │ │ │ │ ├── last_name.txt │ │ │ │ │ │ │ └── email_address.txt │ │ │ │ │ ├── Deliverfile │ │ │ │ │ ├── Appfile │ │ │ │ │ └── Matchfile │ │ │ │ ├── Gemfile │ │ │ │ ├── App │ │ │ │ │ ├── Assets.xcassets │ │ │ │ │ │ ├── Contents.json │ │ │ │ │ │ ├── Splash.imageset │ │ │ │ │ │ │ ├── splash-2732x2732.png │ │ │ │ │ │ │ ├── splash-2732x2732-1.png │ │ │ │ │ │ │ ├── splash-2732x2732-2.png │ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ │ │ ├── AppIcon-512@2x.png │ │ │ │ │ │ │ ├── AppIcon-20x20@1x.png │ │ │ │ │ │ │ ├── AppIcon-20x20@2x-1.png │ │ │ │ │ │ │ ├── AppIcon-20x20@2x.png │ │ │ │ │ │ │ ├── AppIcon-20x20@3x.png │ │ │ │ │ │ │ ├── AppIcon-29x29@1x.png │ │ │ │ │ │ │ ├── AppIcon-29x29@2x-1.png │ │ │ │ │ │ │ ├── AppIcon-29x29@2x.png │ │ │ │ │ │ │ ├── AppIcon-29x29@3x.png │ │ │ │ │ │ │ ├── AppIcon-40x40@1x.png │ │ │ │ │ │ │ ├── AppIcon-40x40@2x-1.png │ │ │ │ │ │ │ ├── AppIcon-40x40@2x.png │ │ │ │ │ │ │ ├── AppIcon-40x40@3x.png │ │ │ │ │ │ │ ├── AppIcon-60x60@2x.png │ │ │ │ │ │ │ ├── AppIcon-60x60@3x.png │ │ │ │ │ │ │ ├── AppIcon-76x76@1x.png │ │ │ │ │ │ │ ├── AppIcon-76x76@2x.png │ │ │ │ │ │ │ └── AppIcon-83.5x83.5@2x.png │ │ │ │ │ ├── config.xml │ │ │ │ │ └── entitlements.mac.plist │ │ │ │ ├── App.xcodeproj │ │ │ │ │ └── project.xcworkspace │ │ │ │ │ │ └── contents.xcworkspacedata │ │ │ │ └── App.xcworkspace │ │ │ │ │ ├── xcshareddata │ │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ │ └── contents.xcworkspacedata │ │ │ └── .gitignore │ │ ├── capacitor-flag.d.ts │ │ ├── capacitor.config.json │ │ └── package.json │ ├── public │ │ ├── favicon.ico │ │ ├── robots.txt │ │ ├── meta-image.png │ │ ├── icons │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon-96x96.png │ │ │ ├── favicon-128x128.png │ │ │ └── white-logo-transparent.png │ │ ├── applications │ │ │ ├── mind-map.webp │ │ │ ├── diagram-thumbnail.webp │ │ │ ├── flashcards-thumbnail.webp │ │ │ ├── biology-study-thumbnail.webp │ │ │ ├── cheat-sheet-thumbnail.webp │ │ │ ├── family-tree-thumbnail.webp │ │ │ ├── history-study-thumbnail.webp │ │ │ ├── kanban-board-thumbnail.webp │ │ │ ├── link-gallery-thumbnail.webp │ │ │ ├── physics-study-thumbnail.webp │ │ │ ├── chemistry-study-thumbnail.webp │ │ │ ├── database-structure-thumbnail.webp │ │ │ └── philosophy-study-thumbnail.webp │ │ ├── whitepaper │ │ │ ├── registration.webp │ │ │ ├── authentication.webp │ │ │ ├── key-hierarchy.webp │ │ │ └── session-refresh.webp │ │ └── help │ │ │ ├── creating-group │ │ │ ├── new-group.webp │ │ │ ├── create-new-page.webp │ │ │ ├── new-page-dialog.webp │ │ │ ├── create-with-options.webp │ │ │ └── new-page-dialog-group.webp │ │ │ ├── inviting-users │ │ │ ├── invite-user-dialog.webp │ │ │ ├── group-settings-button.webp │ │ │ ├── group-settings-tabs.webp │ │ │ ├── accept-reject-invitation.webp │ │ │ └── invite-new-member-button.webp │ │ │ └── joining-group │ │ │ ├── request-access-dialog.webp │ │ │ └── request-access-screen.webp │ ├── .eslintignore │ ├── src-electron │ │ ├── icons │ │ │ ├── icon.icns │ │ │ ├── icon.ico │ │ │ └── icon.png │ │ ├── appx │ │ │ ├── StoreLogo.png │ │ │ ├── Square44x44Logo.png │ │ │ ├── Wide310x150Logo.png │ │ │ └── Square150x150Logo.png │ │ ├── electron-env.d.ts │ │ └── electron-flag.d.ts │ ├── sign-apk.sh │ ├── src-ssr │ │ └── ssr-flag.d.ts │ ├── tsup.config.ts │ └── .gitignore ├── collab-server │ ├── src │ │ ├── types │ │ │ ├── ws.d.ts │ │ │ └── http.d.ts │ │ ├── data │ │ │ ├── redis.ts │ │ │ └── data-abstraction.ts │ │ ├── index.ts │ │ └── env.ts │ ├── .eslintrc.js │ ├── tsup.config.ts │ └── Dockerfile ├── realtime-server │ ├── src │ │ ├── types │ │ │ ├── ws.d.ts │ │ │ └── http.d.ts │ │ ├── data │ │ │ ├── redis.ts │ │ │ └── data-abstraction.ts │ │ ├── index.ts │ │ └── env.ts │ ├── .eslintrc.js │ ├── tsup.config.ts │ └── Dockerfile ├── manager │ ├── src │ │ ├── stripe.ts │ │ ├── data │ │ │ ├── redis.ts │ │ │ └── data-abstraction.ts │ │ └── env.ts │ ├── .eslintrc.js │ └── tsup.config.ts ├── app-server │ ├── src │ │ ├── stripe.ts │ │ ├── data │ │ │ ├── redis.ts │ │ │ └── data-abstraction.ts │ │ ├── trpc │ │ │ ├── api │ │ │ │ ├── users │ │ │ │ │ ├── account │ │ │ │ │ │ ├── email-change │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── two-factor-auth │ │ │ │ │ │ │ ├── enable │ │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ └── stripe │ │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── pages │ │ │ │ │ │ ├── notifications │ │ │ │ │ │ └── index.ts │ │ │ │ │ │ ├── get-starting-page-id.ts │ │ │ │ │ │ ├── clear-recent-pages.ts │ │ │ │ │ │ ├── clear-favorite-pages.ts │ │ │ │ │ │ ├── set-encrypted-default-note.ts │ │ │ │ │ │ └── set-encrypted-default-arrow.ts │ │ │ │ ├── pages │ │ │ │ │ ├── backlinks │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── snapshots │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── deletion │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── groups │ │ │ │ │ ├── privacy │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── password │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── deletion │ │ │ │ │ │ └── index.ts │ │ │ │ │ └── index.ts │ │ │ │ └── sessions │ │ │ │ │ └── index.ts │ │ │ ├── server.ts │ │ │ └── router.ts │ │ ├── index.ts │ │ └── env.ts │ ├── .eslintrc.js │ ├── tsup.config.ts │ └── Dockerfile └── scheduler │ ├── src │ ├── data │ │ ├── redis.ts │ │ └── data-abstraction.ts │ └── env.ts │ ├── .eslintrc.js │ ├── tsup.config.ts │ └── Dockerfile ├── .eslintignore ├── keydb.conf ├── packages ├── @deeplib │ ├── db │ │ ├── src │ │ │ ├── index.ts │ │ │ └── models │ │ │ │ ├── device.ts │ │ │ │ ├── notification.ts │ │ │ │ ├── user-page.ts │ │ │ │ ├── page-update.ts │ │ │ │ ├── page-link.ts │ │ │ │ ├── user-notification.ts │ │ │ │ ├── session.ts │ │ │ │ ├── group-join-request.ts │ │ │ │ ├── index.ts │ │ │ │ ├── page-snapshot.ts │ │ │ │ ├── group-member.ts │ │ │ │ ├── page.ts │ │ │ │ ├── group.ts │ │ │ │ └── group-join-invitation.ts │ │ └── .eslintrc.js │ ├── misc │ │ ├── src │ │ │ ├── plans.ts │ │ │ ├── constants.ts │ │ │ ├── snapshots.ts │ │ │ ├── index.ts │ │ │ ├── realtime.ts │ │ │ ├── collab.ts │ │ │ └── tokens.ts │ │ ├── .eslintignore │ │ ├── .prettierrc.json │ │ ├── .eslintrc.js │ │ └── tsconfig.json │ ├── mail │ │ ├── src │ │ │ ├── brevo-types.ts │ │ │ └── send-grid.ts │ │ └── .eslintrc.js │ ├── data │ │ ├── src │ │ │ ├── universal.ts │ │ │ ├── data-hashes │ │ │ │ ├── user │ │ │ │ │ ├── num-free-pages.ts │ │ │ │ │ ├── demo.ts │ │ │ │ │ ├── public-keyring.ts │ │ │ │ │ ├── customer-id.ts │ │ │ │ │ ├── subscription-id.ts │ │ │ │ │ ├── recent-group-ids.ts │ │ │ │ │ ├── starting-page-id.ts │ │ │ │ │ ├── last-notification-read.ts │ │ │ │ │ ├── new.ts │ │ │ │ │ ├── recent-page-ids.ts │ │ │ │ │ ├── favorite-page-ids.ts │ │ │ │ │ ├── two-factor-auth-enabled.ts │ │ │ │ │ ├── personal-group-id.ts │ │ │ │ │ ├── plan.ts │ │ │ │ │ ├── encrypted-default-arrow.ts │ │ │ │ │ ├── encrypted-default-note.ts │ │ │ │ │ ├── encrypted-name.ts │ │ │ │ │ └── email.ts │ │ │ │ ├── page │ │ │ │ │ ├── free.ts │ │ │ │ │ ├── next-snapshot-date.ts │ │ │ │ │ ├── next-key-rotation-date.ts │ │ │ │ │ ├── next-snapshot-update-index.ts │ │ │ │ │ ├── group-id.ts │ │ │ │ │ ├── exists.ts │ │ │ │ │ ├── permanent-deletion-date.ts │ │ │ │ │ └── encrypted-symmetric-keyring.ts │ │ │ │ ├── customer │ │ │ │ │ ├── user-id.ts │ │ │ │ │ └── index.ts │ │ │ │ ├── group │ │ │ │ │ ├── user-id.ts │ │ │ │ │ ├── main-page-id.ts │ │ │ │ │ ├── access-keyring.ts │ │ │ │ │ ├── public-keyring.ts │ │ │ │ │ ├── is-personal.ts │ │ │ │ │ ├── are-join-requests-allowed.ts │ │ │ │ │ ├── is-password-protected.ts │ │ │ │ │ ├── is-public.ts │ │ │ │ │ ├── exists.ts │ │ │ │ │ ├── permanent-deletion-date.ts │ │ │ │ │ ├── encrypted-content-keyring.ts │ │ │ │ │ └── encrypted-private-keyring.ts │ │ │ │ ├── email │ │ │ │ │ └── user-id.ts │ │ │ │ ├── session │ │ │ │ │ ├── invalidated.ts │ │ │ │ │ └── user-id.ts │ │ │ │ ├── user-page │ │ │ │ │ └── last-parent-id.ts │ │ │ │ ├── group-member │ │ │ │ │ ├── encrypted-access-keyring.ts │ │ │ │ │ └── encrypted-internal-keyring.ts │ │ │ │ ├── group-join-request │ │ │ │ │ └── encrypted-name-for-user.ts │ │ │ │ └── group-join-invitation │ │ │ │ │ └── encrypted-name-for-user.ts │ │ │ └── index.ts │ │ └── .eslintrc.js │ └── tsconfig │ │ └── package.json ├── @stdlib │ ├── color │ │ ├── src │ │ │ └── index.ts │ │ ├── .eslintrc.js │ │ └── tsconfig.json │ ├── data │ │ ├── src │ │ │ ├── universal.ts │ │ │ ├── index.ts │ │ │ └── data-publishing.ts │ │ ├── .eslintrc.js │ │ └── tsconfig.json │ ├── misc │ │ ├── src │ │ │ ├── urls.ts │ │ │ ├── arrays.ts │ │ │ ├── data.ts │ │ │ ├── emails.ts │ │ │ ├── line.ts │ │ │ ├── hash.ts │ │ │ ├── range.ts │ │ │ ├── responsive.ts │ │ │ ├── math.ts │ │ │ ├── logger.ts │ │ │ └── uuid.ts │ │ ├── .eslintrc.js │ │ └── tsconfig.json │ ├── testing │ │ ├── src │ │ │ ├── index.ts │ │ │ ├── inline-mock.ts │ │ │ └── inline-mock.spec.ts │ │ ├── .eslintrc.js │ │ └── tsconfig.json │ ├── vue │ │ ├── src │ │ │ └── index.ts │ │ ├── .eslintrc.js │ │ └── tsconfig.json │ ├── base64 │ │ ├── src │ │ │ ├── is-base64.ts │ │ │ ├── base64-to-text.ts │ │ │ ├── base64-to-bytes.ts │ │ │ ├── text-to-base64.ts │ │ │ ├── index.ts │ │ │ ├── base64-to-bytes-safe.ts │ │ │ ├── bytes-to-base64-safe.ts │ │ │ └── bytes-to-base64.ts │ │ ├── .eslintrc.js │ │ └── tsconfig.json │ ├── crypto │ │ ├── src │ │ │ ├── keys │ │ │ │ └── public-key.ts │ │ │ └── index.ts │ │ └── .eslintrc.js │ ├── db │ │ ├── .eslintrc.js │ │ └── tsconfig.json │ ├── nestjs │ │ ├── .eslintrc.js │ │ └── tsconfig.json │ └── redlock │ │ ├── .eslintrc.js │ │ └── tsconfig.json └── eslint-config-base │ └── package.json ├── pnpm-workspace.yaml ├── .npmrc ├── .syncpackrc.json ├── .husky └── commit-msg ├── .prettierrc.json ├── vitest.config.ts ├── .dockerignore ├── captain-definition-client ├── captain-definition-scheduler ├── .gitignore ├── captain-definition-app-server ├── captain-definition-staging-client ├── captain-definition-collab-server ├── captain-definition-realtime-server ├── captain-definition-staging-app-server ├── captain-definition-staging-scheduler ├── captain-definition-staging-collab-server ├── captain-definition-staging-realtime-server ├── .eslintrc.js ├── turbo.json └── .vscode └── settings.json /.nvmrc: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /apps/client/src/boot/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /keydb.conf: -------------------------------------------------------------------------------- 1 | requirepass keydb_password_here -------------------------------------------------------------------------------- /apps/client/src-capacitor/.gitignore: -------------------------------------------------------------------------------- 1 | /**/capacitor.config.json -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/.gitignore: -------------------------------------------------------------------------------- 1 | /*.json -------------------------------------------------------------------------------- /packages/@deeplib/db/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './models'; 2 | -------------------------------------------------------------------------------- /packages/@stdlib/color/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './color'; 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/id/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/th/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/client/src/boot/stripe.client.ts: -------------------------------------------------------------------------------- 1 | import '@stripe/stripe-js'; 2 | -------------------------------------------------------------------------------- /packages/@stdlib/data/src/universal.ts: -------------------------------------------------------------------------------- 1 | export * from './data-hash'; 2 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/urls.ts: -------------------------------------------------------------------------------- 1 | export const maxUrlLength = 2048; 2 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - 'apps/**' 3 | - 'packages/**' 4 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/.gitignore: -------------------------------------------------------------------------------- 1 | /build/* 2 | !/build/.npmkeep -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/de-DE/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/es-419/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/es-ES/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/fr-FR/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/it-IT/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/ja-JP/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/pt-BR/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/zh-CN/video.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/@deeplib/misc/src/plans.ts: -------------------------------------------------------------------------------- 1 | export type Plan = 'basic' | 'pro'; 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/id/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/th/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/en-US/marketing_url.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/en-US/promotional_text.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /packages/@deeplib/mail/src/brevo-types.ts: -------------------------------------------------------------------------------- 1 | declare module '@getbrevo/brevo'; 2 | -------------------------------------------------------------------------------- /packages/@deeplib/misc/.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | 4 | .eslintrc.js -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/de-DE/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/es-419/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/es-ES/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/fr-FR/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/it-IT/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/ja-JP/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/pt-BR/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/zh-CN/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/primary_first_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/primary_second_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/secondary_category.txt: -------------------------------------------------------------------------------- 1 | UTILITIES 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | shamefully-hoist=true 2 | auto-install-peers=true 3 | strict-peer-dependencies=false -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/en-US/apple_tv_privacy_policy.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/primary_category.txt: -------------------------------------------------------------------------------- 1 | PRODUCTIVITY 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/secondary_first_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/secondary_second_sub_category.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/zh-CN/short_description.txt: -------------------------------------------------------------------------------- 1 | 深度关联想法的视觉笔记 -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/copyright.txt: -------------------------------------------------------------------------------- 1 | 2023 Gustavo Takachi Toyota 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/review_information/first_name.txt: -------------------------------------------------------------------------------- 1 | Gustavo 2 | -------------------------------------------------------------------------------- /apps/client/src/pages/pages/Pages.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /packages/@deeplib/misc/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": true 4 | } 5 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "fastlane" 4 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/en-US/name.txt: -------------------------------------------------------------------------------- 1 | DeepNotes - Visual Note-taking 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/en-US/subtitle.txt: -------------------------------------------------------------------------------- 1 | Dive into your note universe 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/en-US/support_url.txt: -------------------------------------------------------------------------------- 1 | https://deepnotes.app/ 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/review_information/last_name.txt: -------------------------------------------------------------------------------- 1 | Takachi Toyota 2 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/universal.ts: -------------------------------------------------------------------------------- 1 | export * from './data-hashes'; 2 | export * from './utils'; 3 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/title.txt: -------------------------------------------------------------------------------- 1 | DeepNotes - Visual Note-taking -------------------------------------------------------------------------------- /packages/@stdlib/testing/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './inline-mock'; 2 | export * from './smart-mock'; 3 | -------------------------------------------------------------------------------- /.syncpackrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "source": ["package.json", "apps/**/package.json", "packages/**/package.json"] 3 | } 4 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/ja-JP/short_description.txt: -------------------------------------------------------------------------------- 1 | 深く相互に関連したアイデアを視覚的にメモを取る -------------------------------------------------------------------------------- /apps/client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/favicon.ico -------------------------------------------------------------------------------- /apps/client/public/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: /pages/ 3 | Disallow: /groups/ 4 | Disallow: /account/ 5 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/video.txt: -------------------------------------------------------------------------------- 1 | https://www.youtube.com/watch?v=cr2TRWF46Ik -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/en-US/privacy_url.txt: -------------------------------------------------------------------------------- 1 | https://deepnotes.app/privacy-policy 2 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/review_information/email_address.txt: -------------------------------------------------------------------------------- 1 | gustavottoyota@gmail.com 2 | -------------------------------------------------------------------------------- /apps/client/src/i18n/index.ts: -------------------------------------------------------------------------------- 1 | import enUS from './en-US'; 2 | 3 | export default { 4 | 'en-US': enUS, 5 | }; 6 | -------------------------------------------------------------------------------- /.husky/commit-msg: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | npx --no -- commitlint --edit ${1} 5 | -------------------------------------------------------------------------------- /apps/client/src/assets/main.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/assets/main.mp4 -------------------------------------------------------------------------------- /apps/client/src/assets/notes.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/assets/notes.mp4 -------------------------------------------------------------------------------- /apps/client/public/meta-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/meta-image.png -------------------------------------------------------------------------------- /apps/client/src/assets/collab.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/assets/collab.mp4 -------------------------------------------------------------------------------- /apps/client/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist 2 | /src-capacitor 3 | /src-cordova 4 | /.quasar 5 | /node_modules 6 | .eslintrc.js 7 | /src-ssr 8 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/zh-CN/full_description.txt: -------------------------------------------------------------------------------- 1 | DeepNotes 是一种开源、端到端加密的可视化笔记工具,具有深度双向页面导航和实时协作。 -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | Visual Note-Taking for Deeply Interconnected Ideas -------------------------------------------------------------------------------- /apps/client/src-electron/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-electron/icons/icon.icns -------------------------------------------------------------------------------- /apps/client/src-electron/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-electron/icons/icon.ico -------------------------------------------------------------------------------- /apps/client/src-electron/icons/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-electron/icons/icon.png -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "semi": true, 4 | "trailingComma": "all", 5 | "singleAttributePerLine": true 6 | } 7 | -------------------------------------------------------------------------------- /apps/client/public/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/icons/favicon-16x16.png -------------------------------------------------------------------------------- /apps/client/public/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/icons/favicon-32x32.png -------------------------------------------------------------------------------- /apps/client/public/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/icons/favicon-96x96.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/de-DE/short_description.txt: -------------------------------------------------------------------------------- 1 | Visuelle Notizen für tief miteinander verbundene Ideen -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/th/short_description.txt: -------------------------------------------------------------------------------- 1 | การจดบันทึกด้วยภาพสำหรับแนวคิดที่เชื่อมโยงกันอย่างลึกซึ้ง -------------------------------------------------------------------------------- /apps/client/src/assets/platforms/mac.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/assets/platforms/mac.webp -------------------------------------------------------------------------------- /apps/client/public/applications/mind-map.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/mind-map.webp -------------------------------------------------------------------------------- /apps/client/public/icons/favicon-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/icons/favicon-128x128.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/es-ES/short_description.txt: -------------------------------------------------------------------------------- 1 | Toma de notas visual para ideas profundamente interconectadas -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/it-IT/short_description.txt: -------------------------------------------------------------------------------- 1 | Prendere appunti visivi per idee profondamente interconnesse -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/pt-BR/short_description.txt: -------------------------------------------------------------------------------- 1 | Anotações visuais para ideias profundamente interconectadas -------------------------------------------------------------------------------- /apps/client/src-electron/appx/StoreLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-electron/appx/StoreLogo.png -------------------------------------------------------------------------------- /apps/client/src/assets/platforms/linux.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/assets/platforms/linux.webp -------------------------------------------------------------------------------- /apps/client/src/assets/platforms/windows.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/assets/platforms/windows.webp -------------------------------------------------------------------------------- /apps/client/public/whitepaper/registration.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/whitepaper/registration.webp -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/es-419/short_description.txt: -------------------------------------------------------------------------------- 1 | Toma de notas visual para ideas profundamente interconectadas -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/id/short_description.txt: -------------------------------------------------------------------------------- 1 | Pengambilan Catatan Visual untuk Ide yang Sangat Saling Terhubung -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /apps/client/src/assets/badges/google-play.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/assets/badges/google-play.webp -------------------------------------------------------------------------------- /apps/client/src/assets/white-logo-outline.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/assets/white-logo-outline.webp -------------------------------------------------------------------------------- /apps/client/src/css/fonts/Inter/Inter-Black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/css/fonts/Inter/Inter-Black.ttf -------------------------------------------------------------------------------- /apps/client/src/css/fonts/Inter/Inter-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/css/fonts/Inter/Inter-Bold.ttf -------------------------------------------------------------------------------- /apps/client/src/css/fonts/Inter/Inter-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/css/fonts/Inter/Inter-Light.ttf -------------------------------------------------------------------------------- /apps/client/src/css/fonts/Inter/Inter-Thin.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/css/fonts/Inter/Inter-Thin.ttf -------------------------------------------------------------------------------- /apps/client/public/whitepaper/authentication.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/whitepaper/authentication.webp -------------------------------------------------------------------------------- /apps/client/public/whitepaper/key-hierarchy.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/whitepaper/key-hierarchy.webp -------------------------------------------------------------------------------- /apps/client/public/whitepaper/session-refresh.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/whitepaper/session-refresh.webp -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/fr-FR/short_description.txt: -------------------------------------------------------------------------------- 1 | Prise de notes visuelles pour des idées profondément interconnectées -------------------------------------------------------------------------------- /apps/client/src-electron/appx/Square44x44Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-electron/appx/Square44x44Logo.png -------------------------------------------------------------------------------- /apps/client/src-electron/appx/Wide310x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-electron/appx/Wide310x150Logo.png -------------------------------------------------------------------------------- /apps/client/src/css/fonts/Inter/Inter-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/css/fonts/Inter/Inter-Medium.ttf -------------------------------------------------------------------------------- /apps/client/src/css/fonts/Inter/Inter-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/css/fonts/Inter/Inter-Regular.ttf -------------------------------------------------------------------------------- /apps/client/src/css/fonts/Inter/Inter-SemiBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/css/fonts/Inter/Inter-SemiBold.ttf -------------------------------------------------------------------------------- /apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayNonExistentScreen.vue: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /apps/collab-server/src/types/ws.d.ts: -------------------------------------------------------------------------------- 1 | import 'ws'; 2 | 3 | declare module 'ws' { 4 | interface WebSocket { 5 | aux: SocketAuxObject; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /apps/realtime-server/src/types/ws.d.ts: -------------------------------------------------------------------------------- 1 | import 'ws'; 2 | 3 | declare module 'ws' { 4 | interface WebSocket { 5 | aux: SocketAuxObject; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/arrays.ts: -------------------------------------------------------------------------------- 1 | export function isIncluded(value: any, array: any[] | string): boolean { 2 | return array.includes(value); 3 | } 4 | -------------------------------------------------------------------------------- /apps/client/public/icons/white-logo-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/icons/white-logo-transparent.png -------------------------------------------------------------------------------- /apps/client/src-electron/appx/Square150x150Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-electron/appx/Square150x150Logo.png -------------------------------------------------------------------------------- /apps/client/src/css/fonts/Inter/Inter-ExtraBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/css/fonts/Inter/Inter-ExtraBold.ttf -------------------------------------------------------------------------------- /apps/client/src/css/fonts/Inter/Inter-ExtraLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src/css/fonts/Inter/Inter-ExtraLight.ttf -------------------------------------------------------------------------------- /packages/@deeplib/misc/src/constants.ts: -------------------------------------------------------------------------------- 1 | export const maxGroupNameLength = 100; 2 | export const maxPageTitleLength = 100; 3 | export const maxNameLength = 50; 4 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitest/config'; 2 | 3 | export default defineConfig({ 4 | test: { 5 | globals: true, 6 | }, 7 | }); 8 | -------------------------------------------------------------------------------- /apps/client/public/applications/diagram-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/diagram-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/help/creating-group/new-group.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/creating-group/new-group.webp -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/en-US/keywords.txt: -------------------------------------------------------------------------------- 1 | notes,note,note-taking,visual,visual note-taking,encrypted,secure,end-to-end encrypted,deep 2 | -------------------------------------------------------------------------------- /apps/client/src/boot/syncedstore.client.ts: -------------------------------------------------------------------------------- 1 | import { enableVueBindings } from '@syncedstore/core'; 2 | import * as Vue from 'vue'; 3 | 4 | enableVueBindings(Vue); 5 | -------------------------------------------------------------------------------- /apps/collab-server/src/types/http.d.ts: -------------------------------------------------------------------------------- 1 | import 'http'; 2 | 3 | declare module 'http' { 4 | interface IncomingMessage { 5 | sessionId?: string; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /apps/realtime-server/src/types/http.d.ts: -------------------------------------------------------------------------------- 1 | import 'http'; 2 | 3 | declare module 'http' { 4 | interface IncomingMessage { 5 | sessionId?: string; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /apps/client/public/applications/flashcards-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/flashcards-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/ja-JP/full_description.txt: -------------------------------------------------------------------------------- 1 | DeepNotes は、オープンソースのエンドツーエンド暗号化されたビジュアルメモ作成ツールであり、詳細な双方向ページナビゲーションとライブコラボレーションを備えています。 -------------------------------------------------------------------------------- /apps/client/src/code/internals.ts: -------------------------------------------------------------------------------- 1 | import type { DeepNotesInternals } from 'src/boot/internals.universal'; 2 | 3 | export const internals = {} as DeepNotesInternals; 4 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | 3 | **/.env 4 | 5 | **/dist/ 6 | 7 | **/node_modules/ 8 | 9 | **/Dockerfile 10 | .dockerignore 11 | 12 | **/*.log 13 | 14 | **/*.tsbuildinfo -------------------------------------------------------------------------------- /apps/client/public/applications/biology-study-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/biology-study-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/applications/cheat-sheet-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/cheat-sheet-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/applications/family-tree-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/family-tree-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/applications/history-study-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/history-study-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/applications/kanban-board-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/kanban-board-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/applications/link-gallery-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/link-gallery-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/applications/physics-study-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/physics-study-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/help/creating-group/create-new-page.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/creating-group/create-new-page.webp -------------------------------------------------------------------------------- /apps/client/public/help/creating-group/new-page-dialog.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/creating-group/new-page-dialog.webp -------------------------------------------------------------------------------- /packages/@stdlib/vue/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './computed-dict'; 2 | export * from './smart-computed'; 3 | export * from './smart-computed-dict'; 4 | export * from './vue'; 5 | -------------------------------------------------------------------------------- /apps/client/public/applications/chemistry-study-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/chemistry-study-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/help/inviting-users/invite-user-dialog.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/inviting-users/invite-user-dialog.webp -------------------------------------------------------------------------------- /packages/@stdlib/base64/src/is-base64.ts: -------------------------------------------------------------------------------- 1 | import { Base64 } from 'js-base64'; 2 | 3 | export function isBase64(input: string): boolean { 4 | return Base64.isValid(input); 5 | } 6 | -------------------------------------------------------------------------------- /packages/@stdlib/data/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './data-abstraction'; 2 | export * from './data-field'; 3 | export * from './data-hash'; 4 | export * from './data-publishing'; 5 | -------------------------------------------------------------------------------- /apps/client/public/applications/database-structure-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/database-structure-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/applications/philosophy-study-thumbnail.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/applications/philosophy-study-thumbnail.webp -------------------------------------------------------------------------------- /apps/client/public/help/creating-group/create-with-options.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/creating-group/create-with-options.webp -------------------------------------------------------------------------------- /apps/client/public/help/creating-group/new-page-dialog-group.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/creating-group/new-page-dialog-group.webp -------------------------------------------------------------------------------- /apps/client/public/help/inviting-users/group-settings-button.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/inviting-users/group-settings-button.webp -------------------------------------------------------------------------------- /apps/client/public/help/inviting-users/group-settings-tabs.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/inviting-users/group-settings-tabs.webp -------------------------------------------------------------------------------- /apps/client/public/help/joining-group/request-access-dialog.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/joining-group/request-access-dialog.webp -------------------------------------------------------------------------------- /apps/client/public/help/joining-group/request-access-screen.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/joining-group/request-access-screen.webp -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/pages/deletion/delete.ts: -------------------------------------------------------------------------------- 1 | export async function deletePage(pageId: string) { 2 | await trpcClient.pages.deletion.delete.mutate({ pageId }); 3 | } 4 | -------------------------------------------------------------------------------- /packages/@stdlib/base64/src/base64-to-text.ts: -------------------------------------------------------------------------------- 1 | import { Base64 } from 'js-base64'; 2 | 3 | export function base64ToText(input: string): string { 4 | return Base64.decode(input); 5 | } 6 | -------------------------------------------------------------------------------- /apps/client/public/help/inviting-users/accept-reject-invitation.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/inviting-users/accept-reject-invitation.webp -------------------------------------------------------------------------------- /apps/client/public/help/inviting-users/invite-new-member-button.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/public/help/inviting-users/invite-new-member-button.webp -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable/splash.png -------------------------------------------------------------------------------- /apps/client/src/components/ResponsiveContainer.vue: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/data.ts: -------------------------------------------------------------------------------- 1 | export function getFullKey( 2 | prefix: string, 3 | suffix: string, 4 | field: string, 5 | ): string { 6 | return `${prefix}:${suffix}>${field}`; 7 | } 8 | -------------------------------------------------------------------------------- /apps/client/src/boot/array-at-polyfill.client.ts: -------------------------------------------------------------------------------- 1 | export {}; 2 | 3 | if (![].at) { 4 | Array.prototype.at = function (pos) { 5 | return this[pos >= 0 ? pos : this.length + pos]; 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/pages/deletion/restore.ts: -------------------------------------------------------------------------------- 1 | export async function restorePageDeletion(pageId: string) { 2 | await trpcClient.pages.deletion.restore.mutate({ pageId }); 3 | } 4 | -------------------------------------------------------------------------------- /apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayRejectedScreen.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /apps/manager/src/stripe.ts: -------------------------------------------------------------------------------- 1 | import Stripe from 'stripe'; 2 | 3 | export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { 4 | apiVersion: '2023-10-16', 5 | maxNetworkRetries: 2, 6 | }); 7 | -------------------------------------------------------------------------------- /packages/@stdlib/base64/src/base64-to-bytes.ts: -------------------------------------------------------------------------------- 1 | import { Base64 } from 'js-base64'; 2 | 3 | export function base64ToBytes(input: string): Uint8Array { 4 | return Base64.toUint8Array(input); 5 | } 6 | -------------------------------------------------------------------------------- /apps/app-server/src/stripe.ts: -------------------------------------------------------------------------------- 1 | import Stripe from 'stripe'; 2 | 3 | export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, { 4 | apiVersion: '2023-10-16', 5 | maxNetworkRetries: 2, 6 | }); 7 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | DeepNotes is an open source, end-to-end encrypted infinite canvas tool with deep page nesting and realtime collaboration. -------------------------------------------------------------------------------- /apps/client/src/components/Gap.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 11 | -------------------------------------------------------------------------------- /apps/client/src/components/InlineGap.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /apps/client/src-electron/electron-env.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | declare namespace NodeJS { 4 | interface ProcessEnv { 5 | QUASAR_ELECTRON_PRELOAD: string; 6 | APP_URL: string; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/client/src/boot/sodium.universal.ts: -------------------------------------------------------------------------------- 1 | import sodium from 'libsodium-wrappers-sumo'; 2 | import { boot } from 'quasar/wrappers'; 3 | 4 | export default boot(async () => { 5 | await sodium.ready; 6 | }); 7 | -------------------------------------------------------------------------------- /packages/@stdlib/crypto/src/keys/public-key.ts: -------------------------------------------------------------------------------- 1 | export interface PublicKey { 2 | value: Uint8Array; 3 | } 4 | 5 | export function wrapPublicKey(value: Uint8Array): PublicKey { 6 | return { value }; 7 | } 8 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable-land-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable-land-hdpi/splash.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable-land-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable-land-mdpi/splash.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable-port-hdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable-port-hdpi/splash.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable-port-mdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable-port-mdpi/splash.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | -------------------------------------------------------------------------------- /captain-definition-client: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "caproverName": "captain-01", 4 | "caproverApp": "deepnotes-client", 5 | "branch": "dev", 6 | "dockerfilePath": "./apps/client/Dockerfile" 7 | } 8 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/java/app/deepnotes/MainActivity.java: -------------------------------------------------------------------------------- 1 | package app.deepnotes; 2 | 3 | import com.getcapacitor.BridgeActivity; 4 | 5 | public class MainActivity extends BridgeActivity {} 6 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable-land-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable-land-xhdpi/splash.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable-land-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable-land-xxhdpi/splash.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable-port-xhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable-port-xhdpi/splash.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable-port-xxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable-port-xxhdpi/splash.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/th/full_description.txt: -------------------------------------------------------------------------------- 1 | DeepNotes เป็นเครื่องมือจดบันทึกด้วยภาพที่เข้ารหัสแบบโอเพ่นซอร์สแบบ end-to-end พร้อมการนำทางหน้าแบบสองทิศทางเชิงลึกและการทำงานร่วมกันแบบสด -------------------------------------------------------------------------------- /captain-definition-scheduler: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "caproverName": "captain-01", 4 | "caproverApp": "deepnotes-scheduler", 5 | "branch": "dev", 6 | "dockerfilePath": "./apps/scheduler/Dockerfile" 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | .env* 4 | 5 | dist 6 | 7 | .quasar 8 | 9 | *.log 10 | 11 | *.tsbuildinfo 12 | 13 | *.keystore 14 | 15 | .DS_Store 16 | 17 | deploy-*.sh 18 | 19 | postgres_data 20 | keydb_data -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable-land-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable-land-xxxhdpi/splash.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/drawable-port-xxxhdpi/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/drawable-port-xxxhdpi/splash.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/id/full_description.txt: -------------------------------------------------------------------------------- 1 | DeepNotes adalah open source, alat pencatat visual terenkripsi end-to-end dengan navigasi halaman dua arah yang mendalam dan kolaborasi langsung. -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/pages/deletion/delete-permanently.ts: -------------------------------------------------------------------------------- 1 | export async function deletePagePermanently(pageId: string) { 2 | await trpcClient.pages.deletion.deletePermanently.mutate({ pageId }); 3 | } 4 | -------------------------------------------------------------------------------- /apps/client/src/components/ViewportLoadingOverlay.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /apps/client/src/i18n/en-US/index.ts: -------------------------------------------------------------------------------- 1 | // This is just an example, 2 | // so you can safely delete all default props below 3 | 4 | export default { 5 | failed: 'Action failed', 6 | success: 'Action was successful', 7 | }; 8 | -------------------------------------------------------------------------------- /captain-definition-app-server: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "caproverName": "captain-01", 4 | "caproverApp": "deepnotes-app-server", 5 | "branch": "dev", 6 | "dockerfilePath": "./apps/app-server/Dockerfile" 7 | } 8 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/Deliverfile: -------------------------------------------------------------------------------- 1 | # The Deliverfile allows you to store various App Store Connect metadata 2 | # For more information, check out the docs 3 | # https://docs.fastlane.tools/actions/deliver/ 4 | -------------------------------------------------------------------------------- /apps/client/src/boot/http-headers/disable-cache.universal.ts: -------------------------------------------------------------------------------- 1 | import { boot } from 'quasar/wrappers'; 2 | 3 | export default boot(async ({ ssrContext }) => { 4 | ssrContext?.res.setHeader('Cache-Control', 'no-store'); 5 | }); 6 | -------------------------------------------------------------------------------- /apps/client/src/boot/http-headers/x-frame-options.universal.ts: -------------------------------------------------------------------------------- 1 | import { boot } from 'quasar/wrappers'; 2 | 3 | export default boot(async ({ ssrContext }) => { 4 | ssrContext?.res.setHeader('X-Frame-Options', 'DENY'); 5 | }); 6 | -------------------------------------------------------------------------------- /captain-definition-staging-client: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "caproverName": "captain-01", 4 | "caproverApp": "deepnotes-staging-client", 5 | "branch": "dev", 6 | "dockerfilePath": "./apps/client/Dockerfile" 7 | } 8 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png -------------------------------------------------------------------------------- /apps/client/src/boot/http-headers/referrer-policy.universal.ts: -------------------------------------------------------------------------------- 1 | import { boot } from 'quasar/wrappers'; 2 | 3 | export default boot(async ({ ssrContext }) => { 4 | ssrContext?.res.setHeader('Referrer-Policy', 'no-referrer'); 5 | }); 6 | -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/groups/deletion/delete.ts: -------------------------------------------------------------------------------- 1 | export async function deleteGroup(input: { groupId: string }) { 2 | await trpcClient.groups.deletion.delete.mutate({ 3 | groupId: input.groupId, 4 | }); 5 | } 6 | -------------------------------------------------------------------------------- /captain-definition-collab-server: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "caproverName": "captain-01", 4 | "caproverApp": "deepnotes-collab-server", 5 | "branch": "dev", 6 | "dockerfilePath": "./apps/collab-server/Dockerfile" 7 | } 8 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/de-DE/full_description.txt: -------------------------------------------------------------------------------- 1 | DeepNotes ist ein quelloffenes, Ende-zu-Ende-verschlüsseltes visuelles Notizentool mit umfassender bidirektionaler Seitennavigation und Live-Zusammenarbeit. -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/featureGraphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/featureGraphic.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/groups/deletion/restore.ts: -------------------------------------------------------------------------------- 1 | export async function restoreGroup(input: { groupId: string }) { 2 | await trpcClient.groups.deletion.restore.mutate({ 3 | groupId: input.groupId, 4 | }); 5 | } 6 | -------------------------------------------------------------------------------- /captain-definition-realtime-server: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "caproverName": "captain-01", 4 | "caproverApp": "deepnotes-realtime-server", 5 | "branch": "dev", 6 | "dockerfilePath": "./apps/realtime-server/Dockerfile" 7 | } 8 | -------------------------------------------------------------------------------- /captain-definition-staging-app-server: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "caproverName": "captain-01", 4 | "caproverApp": "deepnotes-staging-app-server", 5 | "branch": "dev", 6 | "dockerfilePath": "./apps/app-server/Dockerfile" 7 | } 8 | -------------------------------------------------------------------------------- /captain-definition-staging-scheduler: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "caproverName": "captain-01", 4 | "caproverApp": "deepnotes-staging-scheduler", 5 | "branch": "dev", 6 | "dockerfilePath": "./apps/scheduler/Dockerfile" 7 | } 8 | -------------------------------------------------------------------------------- /packages/eslint-config-base/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-base", 3 | "description": "", 4 | "version": "1.0.0", 5 | "author": "", 6 | "keywords": [], 7 | "license": "ISC", 8 | "main": "index.js" 9 | } 10 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@1x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x-1.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@2x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-20x20@3x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@1x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x-1.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@2x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-29x29@3x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@1x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x-1.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@2x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-40x40@3x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@2x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-60x60@3x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@1x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-76x76@2x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-83.5x83.5@2x.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/client/src/boot/logger.client.ts: -------------------------------------------------------------------------------- 1 | import { mainLogger as _mainLogger } from '@stdlib/misc'; 2 | 3 | export const mainLogger = _mainLogger; 4 | 5 | _mainLogger.operations.unshift( 6 | () => !!process.env.DEV || !!process.env.STAGING, 7 | ); 8 | -------------------------------------------------------------------------------- /apps/client/src/code/cookies.ts: -------------------------------------------------------------------------------- 1 | import { Cookies } from 'quasar'; 2 | 3 | export function clearCookie(name: string, cookies?: Cookies) { 4 | (cookies ?? Cookies).remove(name, { 5 | domain: process.env.HOST, 6 | path: '/', 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /apps/manager/src/data/redis.ts: -------------------------------------------------------------------------------- 1 | import { createRedisInstance } from '@deeplib/data'; 2 | import { once } from 'lodash'; 3 | 4 | export const getRedis = once(() => createRedisInstance()); 5 | export const getSub = once(() => createRedisInstance()); 6 | -------------------------------------------------------------------------------- /apps/scheduler/src/data/redis.ts: -------------------------------------------------------------------------------- 1 | import { createRedisInstance } from '@deeplib/data'; 2 | import { once } from 'lodash'; 3 | 4 | export const getRedis = once(() => createRedisInstance()); 5 | export const getSub = once(() => createRedisInstance()); 6 | -------------------------------------------------------------------------------- /captain-definition-staging-collab-server: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "caproverName": "captain-01", 4 | "caproverApp": "deepnotes-staging-collab-server", 5 | "branch": "dev", 6 | "dockerfilePath": "./apps/collab-server/Dockerfile" 7 | } 8 | -------------------------------------------------------------------------------- /apps/app-server/src/data/redis.ts: -------------------------------------------------------------------------------- 1 | import { createRedisInstance } from '@deeplib/data'; 2 | import { once } from 'lodash'; 3 | 4 | export const getRedis = once(() => createRedisInstance()); 5 | export const getSub = once(() => createRedisInstance()); 6 | -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/pages/snapshots/delete.ts: -------------------------------------------------------------------------------- 1 | export async function deletePageSnapshot(pageId: string, snapshotId: string) { 2 | await trpcClient.pages.snapshots.delete.mutate({ 3 | pageId, 4 | snapshotId, 5 | }); 6 | } 7 | -------------------------------------------------------------------------------- /apps/collab-server/src/data/redis.ts: -------------------------------------------------------------------------------- 1 | import { createRedisInstance } from '@deeplib/data'; 2 | import { once } from 'lodash'; 3 | 4 | export const getRedis = once(() => createRedisInstance()); 5 | export const getSub = once(() => createRedisInstance()); 6 | -------------------------------------------------------------------------------- /captain-definition-staging-realtime-server: -------------------------------------------------------------------------------- 1 | { 2 | "schemaVersion": 2, 3 | "caproverName": "captain-01", 4 | "caproverApp": "deepnotes-staging-realtime-server", 5 | "branch": "dev", 6 | "dockerfilePath": "./apps/realtime-server/Dockerfile" 7 | } 8 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/emails.ts: -------------------------------------------------------------------------------- 1 | export const w3cEmailRegex = 2 | /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; 3 | 4 | export const maxEmailLength = 254; 5 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/account/email-change/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { requestProcedure } from './request'; 4 | 5 | export const emailChangeRouter = trpc.router({ 6 | request: requestProcedure(), 7 | }); 8 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/1_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/2_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/3_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/4_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/5_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/6_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/6_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/7_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/7_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/8_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/phoneScreenshots/8_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/es-ES/full_description.txt: -------------------------------------------------------------------------------- 1 | DeepNotes es una herramienta de código abierto para tomar notas visuales encriptadas de extremo a extremo con navegación de página bidireccional profunda y colaboración en vivo. -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/fr-FR/full_description.txt: -------------------------------------------------------------------------------- 1 | DeepNotes est un outil open source de prise de notes visuelles cryptées de bout en bout avec une navigation de page bidirectionnelle approfondie et une collaboration en direct. -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/it-IT/full_description.txt: -------------------------------------------------------------------------------- 1 | DeepNotes è uno strumento per prendere appunti visivi crittografati end-to-end open source con una profonda navigazione bidirezionale delle pagine e collaborazione dal vivo. -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/pt-BR/full_description.txt: -------------------------------------------------------------------------------- 1 | O DeepNotes é uma ferramenta de anotações visuais criptografadas de ponta a ponta, de código aberto, com navegação de página bidirecional profunda e colaboração em tempo real. -------------------------------------------------------------------------------- /apps/client/src/code/utils/math.ts: -------------------------------------------------------------------------------- 1 | export function roundToMultiple( 2 | value: number, 3 | params: { base: number; roundFunc?: (value: number) => number }, 4 | ) { 5 | return (params.roundFunc ?? Math.round)(value / params.base) * params.base; 6 | } 7 | -------------------------------------------------------------------------------- /apps/realtime-server/src/data/redis.ts: -------------------------------------------------------------------------------- 1 | import { createRedisInstance } from '@deeplib/data'; 2 | import { once } from 'lodash'; 3 | 4 | export const getRedis = once(() => createRedisInstance()); 5 | export const getSub = once(() => createRedisInstance()); 6 | -------------------------------------------------------------------------------- /packages/@deeplib/misc/src/snapshots.ts: -------------------------------------------------------------------------------- 1 | export type PageSnapshotType = 'periodic' | 'manual' | 'pre-restore'; 2 | 3 | export interface PageSnapshotInfo { 4 | id: string; 5 | creationDate: Date; 6 | authorId: string; 7 | type: PageSnapshotType; 8 | } 9 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/1_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/1_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/2_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/2_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/3_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/3_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/4_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/4_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/5_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/5_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/6_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/6_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/7_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/7_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/8_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/sevenInchScreenshots/8_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/1_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/1_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/2_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/2_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/3_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/3_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/4_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/4_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/5_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/5_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/6_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/6_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/7_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/7_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/8_en-US.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DeepNotesApp/DeepNotes/HEAD/apps/client/src-capacitor/android/fastlane/metadata/android/en-US/images/tenInchScreenshots/8_en-US.png -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/es-419/full_description.txt: -------------------------------------------------------------------------------- 1 | DeepNotes es una herramienta de código abierto para tomar notas visuales encriptadas de extremo a extremo con navegación de página bidireccional profunda y colaboración en vivo. -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/num-free-pages.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const numFreePages: DataField = { 5 | columns: ['num_free_pages'], 6 | }; 7 | -------------------------------------------------------------------------------- /packages/@stdlib/base64/src/text-to-base64.ts: -------------------------------------------------------------------------------- 1 | import { Base64 } from 'js-base64'; 2 | 3 | export function textToBase64( 4 | input: string, 5 | params?: { urlSafe?: boolean }, 6 | ): string { 7 | return Base64.encode(input, params?.urlSafe ?? true); 8 | } 9 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/line.ts: -------------------------------------------------------------------------------- 1 | import type { Vec2 } from './vec2'; 2 | 3 | export class Line { 4 | start: Vec2; 5 | end: Vec2; 6 | 7 | constructor(start: Vec2, end: Vec2) { 8 | this.start = start; 9 | this.end = end; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/server.ts: -------------------------------------------------------------------------------- 1 | import { initTRPC } from '@trpc/server'; 2 | import superjson from 'superjson'; 3 | 4 | import type { Context } from './context'; 5 | 6 | export const trpc = initTRPC.context().create({ 7 | transformer: superjson, 8 | }); 9 | -------------------------------------------------------------------------------- /apps/client/sign-apk.sh: -------------------------------------------------------------------------------- 1 | zipalign -f -v 4 ./dist/capacitor/android/apk/release/app-release-unsigned.apk ./dist/capacitor/android/apk/release/app-release-aligned.apk 2 | apksigner sign --ks ./deepnotes.keystore ./dist/capacitor/android/apk/release/app-release-aligned.apk 3 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/xml/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/Appfile: -------------------------------------------------------------------------------- 1 | json_key_file("fastlane/deepnotes-google-api-secret.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one 2 | package_name("app.deepnotes") # e.g. com.krausefx.app 3 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | include ':capacitor-cordova-android-plugins' 3 | project(':capacitor-cordova-android-plugins').projectDir = new File('./capacitor-cordova-android-plugins/') 4 | 5 | apply from: 'capacitor.settings.gradle' -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/groups/deletion/delete-permanently.ts: -------------------------------------------------------------------------------- 1 | export async function deleteGroupPermanently(input: { groupId: string }) { 2 | await trpcClient.groups.deletion.deletePermanently.mutate({ 3 | groupId: input.groupId, 4 | }); 5 | } 6 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/page/free.ts: -------------------------------------------------------------------------------- 1 | import type { PageModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const free: DataField = { 5 | userGettable: () => true, 6 | 7 | columns: ['free'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/page/next-snapshot-date.ts: -------------------------------------------------------------------------------- 1 | import type { PageModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const nextSnapshotDate: DataField = { 5 | columns: ['next_snapshot_date'], 6 | }; 7 | -------------------------------------------------------------------------------- /packages/@stdlib/testing/src/inline-mock.ts: -------------------------------------------------------------------------------- 1 | import { createSmartMock } from './smart-mock'; 2 | 3 | export function createInlineMock(fn: (mock: any) => any) { 4 | const smartMock = createSmartMock(); 5 | 6 | fn(smartMock); 7 | 8 | return smartMock; 9 | } 10 | -------------------------------------------------------------------------------- /apps/client/src/code/pages/page/notes/date.ts: -------------------------------------------------------------------------------- 1 | import { roundToMultiple } from 'src/code/utils/math'; 2 | 3 | export function roundTimeToMinutes(value: number): number { 4 | return roundToMultiple(value, { 5 | base: 60 * 1000, 6 | roundFunc: Math.floor, 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/fastlane/metadata/android/en-US/changelogs/62.txt: -------------------------------------------------------------------------------- 1 | - Fixed page deletion problems 2 | - Added ability to reject group invitations in free account 3 | - Notes now become movable when duplicated 4 | - Group lists now only show groups editable by the user -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/page/next-key-rotation-date.ts: -------------------------------------------------------------------------------- 1 | import type { PageModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const nextKeyRotationDate: DataField = { 5 | columns: ['next_key_rotation_date'], 6 | }; 7 | -------------------------------------------------------------------------------- /packages/@deeplib/misc/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './collab'; 2 | export * from './constants'; 3 | export * from './notifications'; 4 | export * from './plans'; 5 | export * from './realtime'; 6 | export * from './roles'; 7 | export * from './snapshots'; 8 | export * from './tokens'; 9 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/xml/file_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/en-US/release_notes.txt: -------------------------------------------------------------------------------- 1 | - Improved toolbar buttons 2 | - Added help section 3 | - Fixed delete button in toolbar 4 | - Added panning with Space + Left click 5 | - Added horizontal scrolling with Shift + Mouse wheel 6 | - Many other bug fixes 7 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/page/next-snapshot-update-index.ts: -------------------------------------------------------------------------------- 1 | import type { PageModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const nextSnapshotUpdateIndex: DataField = { 5 | columns: ['next_snapshot_update_index'], 6 | }; 7 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/demo.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const demo: DataField = { 5 | cacheLocally: true, // Reason: Field never changes 6 | 7 | columns: ['demo'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/public-keyring.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const publicKeyring: DataField = { 5 | userGettable: () => true, 6 | 7 | columns: ['public_keyring'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/@deeplib/db/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@stdlib/data/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@stdlib/db/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@stdlib/vue/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { accountRouter } from './account'; 4 | import { pagesRouter } from './pages'; 5 | 6 | export const usersRouter = trpc.router({ 7 | account: accountRouter, 8 | pages: pagesRouter, 9 | }); 10 | -------------------------------------------------------------------------------- /packages/@deeplib/data/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/customer/user-id.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const userId: DataField = { 5 | cacheLocally: true, // Reason: Field never changes 6 | 7 | columns: ['id'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/device.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | 3 | export class DeviceModel extends Model { 4 | static override tableName = 'devices'; 5 | 6 | id!: string; 7 | 8 | user_id!: string; 9 | 10 | hash!: Uint8Array; 11 | 12 | trusted!: boolean; 13 | } 14 | -------------------------------------------------------------------------------- /packages/@deeplib/mail/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@deeplib/misc/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@deeplib/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@deeplib/tsconfig", 3 | "description": "", 4 | "version": "1.0.0", 5 | "author": "", 6 | "files": [ 7 | "base.json", 8 | "lib.json" 9 | ], 10 | "keywords": [], 11 | "license": "ISC", 12 | "main": "index.js" 13 | } 14 | -------------------------------------------------------------------------------- /packages/@stdlib/base64/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@stdlib/color/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@stdlib/crypto/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@stdlib/data/src/data-publishing.ts: -------------------------------------------------------------------------------- 1 | import { nanoidToBytes, once } from '@stdlib/misc'; 2 | import { nanoid } from 'nanoid'; 3 | 4 | export const getSelfPublisherID = once(() => nanoid()); 5 | export const getSelfPublisherIdBytes = once(() => 6 | nanoidToBytes(getSelfPublisherID()), 7 | ); 8 | -------------------------------------------------------------------------------- /packages/@stdlib/nestjs/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@stdlib/redlock/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@stdlib/testing/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js'], 12 | }; 13 | -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/pages/bump.ts: -------------------------------------------------------------------------------- 1 | export async function bumpPage(input: { 2 | pageId: string; 3 | 4 | parentPageId?: string; 5 | }) { 6 | await trpcClient.pages.bump.mutate({ 7 | pageId: input.pageId, 8 | 9 | parentPageId: input.parentPageId, 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /apps/manager/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js', 'tsup.config.ts'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/user-id.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const userId: DataField = { 5 | cacheLocally: true, // Reason: Field never changes 6 | 7 | columns: ['user_id'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/@stdlib/base64/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './base64-to-bytes'; 2 | export * from './base64-to-bytes-safe'; 3 | export * from './base64-to-text'; 4 | export * from './bytes-to-base64'; 5 | export * from './bytes-to-base64-safe'; 6 | export * from './is-base64'; 7 | export * from './text-to-base64'; 8 | -------------------------------------------------------------------------------- /apps/app-server/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js', 'tsup.config.ts'], 12 | }; 13 | -------------------------------------------------------------------------------- /apps/collab-server/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js', 'tsup.config.ts'], 12 | }; 13 | -------------------------------------------------------------------------------- /apps/scheduler/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js', 'tsup.config.ts'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/email/user-id.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const userId: DataField = { 5 | dontCache: true, 6 | 7 | userGettable: () => true, 8 | 9 | columns: ['id'], 10 | }; 11 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-all.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /apps/realtime-server/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: ['dist', 'node_modules', '.eslintrc.js', 'tsup.config.ts'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/customer-id.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const customerId: DataField = { 5 | cacheLocally: true, // Reason: Field never changes 6 | 7 | columns: ['customer_id'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/@stdlib/testing/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@deeplib/tsconfig/base.json", 3 | 4 | "include": ["*.ts", "src/**/*.ts"], 5 | 6 | "compilerOptions": { 7 | "types": ["vitest/globals"], 8 | 9 | "baseUrl": ".", 10 | 11 | "rootDir": "src", 12 | "outDir": "dist" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/.gitignore: -------------------------------------------------------------------------------- 1 | /App/build 2 | /App/Pods 3 | /App/Podfile.lock 4 | /App/App/public 5 | DerivedData 6 | xcuserdata 7 | 8 | # Cordova plugins for Capacitor 9 | /capacitor-cordova-ios-plugins 10 | 11 | # Generated Config files 12 | /App/App/capacitor.config.json 13 | /App/App/config.xml 14 | -------------------------------------------------------------------------------- /apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayErrorScreen.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/index.ts: -------------------------------------------------------------------------------- 1 | import 'objection'; // Necessary for type inference 2 | 3 | export * from './data-hashes'; 4 | export * from './emails'; 5 | export * from './page-updates'; 6 | export * from './redis'; 7 | export * from './roles'; 8 | export * from './snapshots'; 9 | export * from './utils'; 10 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/pages/backlinks/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { createProcedure } from './create'; 4 | import { deleteProcedure } from './delete'; 5 | 6 | export const backlinksRouter = trpc.router({ 7 | create: createProcedure(), 8 | delete: deleteProcedure(), 9 | }); 10 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/entitlements.mac.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.cs.allow-jit 6 | 7 | 8 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/subscription-id.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const subscriptionId: DataField = { 5 | userGettable: ({ userId, suffix }) => userId === suffix, 6 | 7 | columns: ['subscription_id'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/notification.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | 3 | export class NotificationModel extends Model { 4 | static override tableName = 'notifications'; 5 | 6 | id!: number; 7 | 8 | type!: string; 9 | 10 | encrypted_content!: Uint8Array; 11 | 12 | datetime!: Date; 13 | } 14 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/main-page-id.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const mainPageId: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: () => true, 8 | 9 | columns: ['main_page_id'], 10 | }; 11 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/recent-group-ids.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const recentGroupIds: DataField = { 5 | userGettable: ({ userId, suffix }) => userId === suffix, 6 | 7 | columns: ['recent_group_ids'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/starting-page-id.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const startingPageId: DataField = { 5 | userGettable: ({ userId, suffix }) => userId === suffix, 6 | 7 | columns: ['starting_page_id'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/session/invalidated.ts: -------------------------------------------------------------------------------- 1 | import type { SessionModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const invalidated: DataField = { 5 | cacheLocally: true, // Reason: Performance (Field is used frequently) 6 | 7 | columns: ['invalidated'], 8 | }; 9 | -------------------------------------------------------------------------------- /packages/@stdlib/testing/src/inline-mock.spec.ts: -------------------------------------------------------------------------------- 1 | import { createInlineMock } from './inline-mock'; 2 | 3 | describe('Inline Mock', () => { 4 | it('should allow deep access', () => { 5 | const inlineMock = createInlineMock((mock) => (mock().asd().sdf = 1)); 6 | 7 | expect(inlineMock().asd().sdf).toBe(1); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/access-keyring.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const accessKeyring: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: () => true, 8 | 9 | columns: ['access_keyring'], 10 | }; 11 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/public-keyring.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const publicKeyring: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: () => true, 8 | 9 | columns: ['public_keyring'], 10 | }; 11 | -------------------------------------------------------------------------------- /packages/@deeplib/misc/src/realtime.ts: -------------------------------------------------------------------------------- 1 | export enum RealtimeClientMessageType { 2 | REQUEST, 3 | } 4 | 5 | export enum RealtimeServerMessageType { 6 | RESPONSE, 7 | DATA_NOTIFICATION, 8 | USER_NOTIFICATION, 9 | } 10 | 11 | export enum RealtimeCommandType { 12 | HGET, 13 | HSET, 14 | SUBSCRIBE, 15 | UNSUBSCRIBE, 16 | } 17 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/account/two-factor-auth/enable/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { finishProcedure } from './finish'; 4 | import { requestProcedure } from './request'; 5 | 6 | export const enableRouter = trpc.router({ 7 | request: requestProcedure(), 8 | finish: finishProcedure(), 9 | }); 10 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /apps/client/src/boot/helpers.universal.ts: -------------------------------------------------------------------------------- 1 | import { boot } from 'quasar/wrappers'; 2 | 3 | export default boot(async ({ app, store }) => { 4 | $quasar(app.config.globalProperties.$q); 5 | 6 | if (process.env.CLIENT) { 7 | appStore(store); 8 | authStore(store); 9 | uiStore(store); 10 | pagesStore(store); 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/last-notification-read.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const lastNotificationRead: DataField = { 5 | userGettable: ({ userId, suffix }) => userId === suffix, 6 | 7 | columns: ['last_notification_read'], 8 | }; 9 | -------------------------------------------------------------------------------- /apps/app-server/src/data/data-abstraction.ts: -------------------------------------------------------------------------------- 1 | import { dataHashes } from '@deeplib/data'; 2 | import { DataAbstraction } from '@stdlib/data'; 3 | import { once } from 'lodash'; 4 | 5 | import { getRedis, getSub } from './redis'; 6 | 7 | export const dataAbstraction = once( 8 | () => new DataAbstraction(dataHashes, getRedis(), getSub()), 9 | ); 10 | -------------------------------------------------------------------------------- /apps/client/src-ssr/ssr-flag.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // THIS FEATURE-FLAG FILE IS AUTOGENERATED, 3 | // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING 4 | import "quasar/dist/types/feature-flag"; 5 | 6 | declare module "quasar/dist/types/feature-flag" { 7 | interface QuasarFeatureFlags { 8 | ssr: true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/manager/src/data/data-abstraction.ts: -------------------------------------------------------------------------------- 1 | import { dataHashes } from '@deeplib/data'; 2 | import { DataAbstraction } from '@stdlib/data'; 3 | import { once } from 'lodash'; 4 | 5 | import { getRedis, getSub } from './redis'; 6 | 7 | export const dataAbstraction = once( 8 | () => new DataAbstraction(dataHashes, getRedis(), getSub()), 9 | ); 10 | -------------------------------------------------------------------------------- /apps/scheduler/src/data/data-abstraction.ts: -------------------------------------------------------------------------------- 1 | import { dataHashes } from '@deeplib/data'; 2 | import { DataAbstraction } from '@stdlib/data'; 3 | import { once } from 'lodash'; 4 | 5 | import { getRedis, getSub } from './redis'; 6 | 7 | export const dataAbstraction = once( 8 | () => new DataAbstraction(dataHashes, getRedis(), getSub()), 9 | ); 10 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/user-page.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | 3 | export class UserPageModel extends Model { 4 | static override tableName = 'users_pages'; 5 | 6 | static override idColumn = ['user_id', 'page_id']; 7 | 8 | user_id!: string; 9 | page_id!: string; 10 | 11 | last_parent_id!: string | null; 12 | } 13 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/pages/notifications/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { loadProcedure } from './load'; 4 | import { markAsReadProcedure } from './mark-as-read'; 5 | 6 | export const notificationsRouter = trpc.router({ 7 | load: loadProcedure(), 8 | 9 | markAsRead: markAsReadProcedure(), 10 | }); 11 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /apps/client/src/stores/store-flag.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // THIS FEATURE-FLAG FILE IS AUTOGENERATED, 3 | // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING 4 | import "quasar/dist/types/feature-flag"; 5 | 6 | declare module "quasar/dist/types/feature-flag" { 7 | interface QuasarFeatureFlags { 8 | store: true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/collab-server/src/data/data-abstraction.ts: -------------------------------------------------------------------------------- 1 | import { dataHashes } from '@deeplib/data'; 2 | import { DataAbstraction } from '@stdlib/data'; 3 | import { once } from 'lodash'; 4 | 5 | import { getRedis, getSub } from './redis'; 6 | 7 | export const dataAbstraction = once( 8 | () => new DataAbstraction(dataHashes, getRedis(), getSub()), 9 | ); 10 | -------------------------------------------------------------------------------- /apps/realtime-server/src/data/data-abstraction.ts: -------------------------------------------------------------------------------- 1 | import { dataHashes } from '@deeplib/data'; 2 | import { DataAbstraction } from '@stdlib/data'; 3 | import { once } from 'lodash'; 4 | 5 | import { getRedis, getSub } from './redis'; 6 | 7 | export const dataAbstraction = once( 8 | () => new DataAbstraction(dataHashes, getRedis(), getSub()), 9 | ); 10 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/session/user-id.ts: -------------------------------------------------------------------------------- 1 | import type { SessionModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const userId: DataField = { 5 | cacheLocally: true, // Reason: Field never changes 6 | 7 | userGettable: () => true, 8 | 9 | columns: ['user_id'], 10 | }; 11 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/page-update.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | 3 | export class PageUpdateModel extends Model { 4 | static override tableName = 'page_updates'; 5 | 6 | static override idColumn = ['page_id', 'index']; 7 | 8 | page_id!: string; 9 | 10 | index!: number; 11 | 12 | encrypted_data!: Uint8Array; 13 | } 14 | -------------------------------------------------------------------------------- /packages/@deeplib/misc/src/collab.ts: -------------------------------------------------------------------------------- 1 | export enum CollabMessageType { 2 | DOC, 3 | AWARENESS, 4 | } 5 | 6 | export enum CollabServerDocMessageType { 7 | ALL_UPDATES_UNMERGED, 8 | SINGLE_UPDATE, 9 | SINGLE_UPDATE_ACK, 10 | } 11 | 12 | export enum CollabClientDocMessageType { 13 | ALL_UPDATES_UNMERGED_RESPONSE, 14 | SINGLE_UPDATE, 15 | } 16 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/hash.ts: -------------------------------------------------------------------------------- 1 | export function hashFNV1a(str: string, seed = 0x811c9dc5): number { 2 | let hval = seed; 3 | 4 | for (let i = 0, l = str.length; i < l; i++) { 5 | hval ^= str.charCodeAt(i); 6 | hval += 7 | (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24); 8 | } 9 | 10 | return hval >>> 0; 11 | } 12 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/capacitor-flag.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // THIS FEATURE-FLAG FILE IS AUTOGENERATED, 3 | // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING 4 | import "quasar/dist/types/feature-flag"; 5 | 6 | declare module "quasar/dist/types/feature-flag" { 7 | interface QuasarFeatureFlags { 8 | capacitor: true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/client/src-electron/electron-flag.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | // THIS FEATURE-FLAG FILE IS AUTOGENERATED, 3 | // REMOVAL OR CHANGES WILL CAUSE RELATED TYPES TO STOP WORKING 4 | import "quasar/dist/types/feature-flag"; 5 | 6 | declare module "quasar/dist/types/feature-flag" { 7 | interface QuasarFeatureFlags { 8 | electron: true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/manager/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | clean: true, // Clean output directory before each build 5 | 6 | entry: ['src/index.ts'], 7 | format: ['cjs'], 8 | minify: true, 9 | sourcemap: false, 10 | splitting: false, 11 | dts: false, 12 | noExternal: [/^(?!knex|ws).+$/], 13 | }); 14 | -------------------------------------------------------------------------------- /apps/scheduler/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | clean: true, // Clean output directory before each build 5 | 6 | entry: ['src/index.ts'], 7 | format: ['cjs'], 8 | minify: true, 9 | sourcemap: false, 10 | splitting: false, 11 | dts: false, 12 | noExternal: [/^(?!knex|ws).+$/], 13 | }); 14 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | DeepNotes 4 | DeepNotes 5 | app.deepnotes 6 | app.deepnotes 7 | 8 | -------------------------------------------------------------------------------- /apps/collab-server/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | clean: true, // Clean output directory before each build 5 | 6 | entry: ['src/index.ts'], 7 | format: ['cjs'], 8 | minify: true, 9 | sourcemap: false, 10 | splitting: false, 11 | dts: false, 12 | noExternal: [/^(?!knex|ws).+$/], 13 | }); 14 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/new.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const newUser: DataField = { 5 | userGettable: ({ userId, suffix }) => userId === suffix, 6 | userSettable: ({ userId, suffix }) => userId === suffix, 7 | 8 | columns: ['new'], 9 | }; 10 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/recent-page-ids.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const recentPageIds: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: ({ userId, suffix }) => userId === suffix, 8 | 9 | columns: ['recent_page_ids'], 10 | }; 11 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/page-link.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | 3 | export class PageLinkModel extends Model { 4 | static override tableName = 'page_links'; 5 | 6 | static override idColumn = ['target_page_id', 'source_page_id']; 7 | 8 | target_page_id!: string; 9 | source_page_id!: string; 10 | 11 | last_activity_date!: Date; 12 | } 13 | -------------------------------------------------------------------------------- /apps/client/src/stores/app.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia'; 2 | 3 | export const useAppStore = defineStore('app', () => { 4 | const state = reactive({ 5 | loading: true, 6 | 7 | dict: {} as Record, 8 | }); 9 | 10 | return { 11 | ...toRefs(state), 12 | }; 13 | }); 14 | 15 | export type AppStore = ReturnType; 16 | -------------------------------------------------------------------------------- /apps/realtime-server/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | clean: true, // Clean output directory before each build 5 | 6 | entry: ['src/index.ts'], 7 | format: ['cjs'], 8 | minify: true, 9 | sourcemap: false, 10 | splitting: false, 11 | dts: false, 12 | noExternal: [/^(?!knex|ws).+$/], 13 | }); 14 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/favorite-page-ids.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const favoritePageIds: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: ({ userId, suffix }) => userId === suffix, 8 | 9 | columns: ['favorite_page_ids'], 10 | }; 11 | -------------------------------------------------------------------------------- /apps/app-server/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | clean: true, // Clean output directory before each build 5 | 6 | entry: ['src/index.ts'], 7 | format: ['cjs'], 8 | minify: true, 9 | sourcemap: false, 10 | splitting: false, 11 | dts: false, 12 | noExternal: [/^(?!knex|ws|@getbrevo\/brevo).+$/], 13 | }); 14 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/range.ts: -------------------------------------------------------------------------------- 1 | export function rangeStop(start: number, stop: number, step = 1) { 2 | return Array.from( 3 | { length: (stop - start) / step + 1 }, 4 | (_, i) => start + i * step, 5 | ); 6 | } 7 | 8 | export function rangeCount(start: number, count: number, step = 1) { 9 | return Array.from({ length: count }, (_, i) => start + i * step); 10 | } 11 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/pages/snapshots/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { deleteProcedure } from './delete'; 4 | import { loadProcedure } from './load'; 5 | import { saveProcedure } from './save'; 6 | 7 | export const snapshotsRouter = trpc.router({ 8 | save: saveProcedure(), 9 | load: loadProcedure(), 10 | delete: deleteProcedure(), 11 | }); 12 | -------------------------------------------------------------------------------- /apps/client/src/components/CustomInfiniteScroll.vue: -------------------------------------------------------------------------------- 1 | 15 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/two-factor-auth-enabled.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const twoFactorAuthEnabled: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: ({ userId, suffix }) => userId === suffix, 8 | 9 | columns: ['two_factor_auth_enabled'], 10 | }; 11 | -------------------------------------------------------------------------------- /apps/client/src/components/PassthroughComponent.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 19 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/page/group-id.ts: -------------------------------------------------------------------------------- 1 | import type { PageModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const groupId: DataField = { 5 | cacheLocally: true, // Reason: Performance (Field is used frequently) 6 | notifyUpdates: true, 7 | 8 | userGettable: () => true, 9 | 10 | columns: ['group_id'], 11 | }; 12 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/user-notification.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | 3 | export class UserNotificationModel extends Model { 4 | static override tableName = 'users_notifications'; 5 | 6 | static override idColumn = ['user_id', 'notification_id']; 7 | 8 | user_id!: string; 9 | notification_id!: number; 10 | 11 | encrypted_symmetric_key!: Uint8Array; 12 | } 13 | -------------------------------------------------------------------------------- /packages/@stdlib/db/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@deeplib/tsconfig/base.json", 3 | 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | 7 | "rootDir": "src", 8 | "outDir": "dist" 9 | }, 10 | 11 | "include": ["src/**/*.ts"], 12 | 13 | "tsc-alias": { 14 | "replacers": { 15 | "base-url": { 16 | "enabled": false 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /packages/@stdlib/color/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@deeplib/tsconfig/base.json", 3 | 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | 7 | "rootDir": "src", 8 | "outDir": "dist" 9 | }, 10 | 11 | "include": ["src/**/*.ts"], 12 | 13 | "tsc-alias": { 14 | "replacers": { 15 | "base-url": { 16 | "enabled": false 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/groups/privacy/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { makePublicProcedure } from './make-public'; 4 | import { setJoinRequestsAllowedProcedure } from './set-join-requests-allowed'; 5 | 6 | export const privacyRouter = trpc.router({ 7 | makePublic: makePublicProcedure(), 8 | setJoinRequestsAllowed: setJoinRequestsAllowedProcedure(), 9 | }); 10 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/personal-group-id.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const personalGroupId: DataField = { 5 | cacheLocally: true, // Reason: Field never changes 6 | 7 | userGettable: ({ userId, suffix }) => userId === suffix, 8 | 9 | columns: ['personal_group_id'], 10 | }; 11 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/groups/password/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { changeProcedure } from './change'; 4 | import { disableProcedure } from './disable'; 5 | import { enableProcedure } from './enable'; 6 | 7 | export const passwordRouter = trpc.router({ 8 | enable: enableProcedure(), 9 | change: changeProcedure(), 10 | disable: disableProcedure(), 11 | }); 12 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/is-personal.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const isPersonal: DataField = { 5 | cacheLocally: true, // Reason: Field never changes 6 | 7 | userGettable: () => true, 8 | 9 | columns: ['user_id'], 10 | 11 | get: ({ model }) => model?.user_id != null, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user-page/last-parent-id.ts: -------------------------------------------------------------------------------- 1 | import type { UserPageModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | import { splitStr } from '@stdlib/misc'; 4 | 5 | export const lastParentId: DataField = { 6 | userGettable: ({ userId, suffix }) => userId === splitStr(suffix, ':', 2)[0], 7 | 8 | columns: ['last_parent_id'], 9 | }; 10 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/plan.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const plan: DataField = { 5 | cacheLocally: true, // Reason: Performance (Field is used frequently) 6 | notifyUpdates: true, 7 | 8 | userGettable: ({ userId, suffix }) => userId === suffix, 9 | 10 | columns: ['plan'], 11 | }; 12 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/Appfile: -------------------------------------------------------------------------------- 1 | app_identifier("app.deepnotes") # The bundle identifier of your app 2 | apple_id("gustavottoyota@gmail.com") # Your Apple Developer Portal username 3 | 4 | itc_team_id("126468926") # App Store Connect Team ID 5 | team_id("NK86B84G2A") # Developer Portal Team ID 6 | 7 | # For more information about the Appfile, see: 8 | # https://docs.fastlane.tools/advanced/#appfile 9 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/encrypted-default-arrow.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const encryptedDefaultArrow: DataField = { 5 | userGettable: ({ userId, suffix }) => userId === suffix, 6 | userSettable: ({ userId, suffix }) => userId === suffix, 7 | 8 | columns: ['encrypted_default_arrow'], 9 | }; 10 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/encrypted-default-note.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const encryptedDefaultNote: DataField = { 5 | userGettable: ({ userId, suffix }) => userId === suffix, 6 | userSettable: ({ userId, suffix }) => userId === suffix, 7 | 8 | columns: ['encrypted_default_note'], 9 | }; 10 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | 4 | extends: ['base'], 5 | 6 | parserOptions: { 7 | tsconfigRootDir: __dirname, 8 | project: './tsconfig.json', 9 | }, 10 | 11 | ignorePatterns: [ 12 | 'dist', 13 | 'node_modules', 14 | '.eslintrc.js', 15 | 'commitlint.config.js', 16 | 'list-duplicates.js', 17 | 'vitest.config.ts', 18 | 'vite.config.ts', 19 | ], 20 | }; 21 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/encrypted-name.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const encryptedName: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: ({ userId, suffix }) => userId === suffix, 8 | userSettable: ({ userId, suffix }) => userId === suffix, 9 | 10 | columns: ['encrypted_name'], 11 | }; 12 | -------------------------------------------------------------------------------- /packages/@stdlib/base64/src/base64-to-bytes-safe.ts: -------------------------------------------------------------------------------- 1 | import type { Replace } from '@stdlib/misc'; 2 | 3 | import { base64ToBytes } from './base64-to-bytes'; 4 | 5 | export function base64ToBytesSafe( 6 | input: T, 7 | ): Replace { 8 | if (input == null) { 9 | return input as any; 10 | } else { 11 | return base64ToBytes(input) as any; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/client/src/stores/page-selection.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia'; 2 | import { makeStoreFunc } from 'src/code/stores'; 3 | 4 | const _usePageSelection = defineStore('page-selection', () => { 5 | const state = reactive({ 6 | selectedPages: new Set(), 7 | }); 8 | 9 | return { 10 | ...toRefs(state), 11 | }; 12 | }); 13 | 14 | export const pageSelectionStore = makeStoreFunc(_usePageSelection); 15 | -------------------------------------------------------------------------------- /apps/collab-server/src/index.ts: -------------------------------------------------------------------------------- 1 | import './env'; 2 | 3 | import { mainLogger } from '@stdlib/misc'; 4 | 5 | import { initKnex } from './data/knex'; 6 | import { httpServer } from './http-server'; 7 | 8 | initKnex(); 9 | 10 | httpServer().listen(parseInt(process.env.COLLAB_SERVER_PORT), () => { 11 | mainLogger 12 | .sub('index.ts') 13 | .info(`collab-server started on port ${process.env.COLLAB_SERVER_PORT}`); 14 | }); 15 | -------------------------------------------------------------------------------- /packages/@stdlib/base64/src/bytes-to-base64-safe.ts: -------------------------------------------------------------------------------- 1 | import type { Replace } from '@stdlib/misc'; 2 | 3 | import { bytesToBase64 } from './bytes-to-base64'; 4 | 5 | export function bytesToBase64Safe( 6 | input: T, 7 | ): Replace { 8 | if (input == null) { 9 | return input as any; 10 | } else { 11 | return bytesToBase64(input) as any; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /apps/client/src/boot/prosemirror.client.ts: -------------------------------------------------------------------------------- 1 | import { EditorView } from 'prosemirror-view'; 2 | 3 | // Prosemirror fix 4 | 5 | const oldUpdateState = EditorView.prototype.updateState; 6 | 7 | EditorView.prototype.updateState = function (state) { 8 | // This prevents the matchesNode error on hot reloads 9 | // @ts-ignore 10 | if (!this.docView) { 11 | return; 12 | } 13 | 14 | oldUpdateState.call(this, state); 15 | }; 16 | -------------------------------------------------------------------------------- /packages/@stdlib/crypto/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './crypto-js'; 2 | export * from './keyrings/keyring'; 3 | export * from './keyrings/private-keyring'; 4 | export * from './keyrings/symmetric-keyring'; 5 | export * from './keys/key-pair'; 6 | export * from './keys/private-key'; 7 | export * from './keys/public-key'; 8 | export * from './keys/symmetric-key'; 9 | export * from './password-hashing'; 10 | export * from './wrapped-data'; 11 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/account/stripe/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { createCheckoutSessionProcedure } from './create-checkout-session'; 4 | import { createPortalSessionProcedure } from './create-portal-session'; 5 | 6 | export const stripeRouter = trpc.router({ 7 | createCheckoutSession: createCheckoutSessionProcedure(), 8 | createPortalSession: createPortalSessionProcedure(), 9 | }); 10 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/are-join-requests-allowed.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const areJoinRequestsAllowed: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: () => true, 8 | 9 | columns: ['are_join_requests_allowed'], 10 | 11 | get: ({ model }) => model?.are_join_requests_allowed === true, 12 | }; 13 | -------------------------------------------------------------------------------- /apps/app-server/src/index.ts: -------------------------------------------------------------------------------- 1 | import './env'; 2 | import './data/knex'; 3 | 4 | import { mainLogger } from '@stdlib/misc'; 5 | 6 | import { fastify } from './fastify/server'; 7 | 8 | void fastify().then(async (fastify) => { 9 | await fastify.listen({ 10 | port: parseInt(process.env.APP_SERVER_PORT), 11 | host: '0.0.0.0', 12 | }); 13 | 14 | mainLogger.info(`app-server started on port ${process.env.APP_SERVER_PORT}`); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/is-password-protected.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const isPasswordProtected: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: () => true, 8 | 9 | columns: ['encrypted_rehashed_password_hash'], 10 | 11 | get: ({ model }) => model?.encrypted_rehashed_password_hash != null, 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/responsive.ts: -------------------------------------------------------------------------------- 1 | export const BREAKPOINT_SM_MIN = 576; 2 | export const BREAKPOINT_MD_MIN = 768; 3 | export const BREAKPOINT_LG_MIN = 992; 4 | export const BREAKPOINT_XL_MIN = 1200; 5 | 6 | export const BREAKPOINT_XS_MAX = BREAKPOINT_SM_MIN - 1; 7 | export const BREAKPOINT_SM_MAX = BREAKPOINT_MD_MIN - 1; 8 | export const BREAKPOINT_MD_MAX = BREAKPOINT_LG_MIN - 1; 9 | export const BREAKPOINT_LG_MAX = BREAKPOINT_XL_MIN - 1; 10 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/groups/deletion/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { deleteProcedure } from './delete'; 4 | import { deletePermanentlyProcedure } from './delete-permanently'; 5 | import { restoreProcedure } from './restore'; 6 | 7 | export const deletionRouter = trpc.router({ 8 | delete: deleteProcedure(), 9 | restore: restoreProcedure(), 10 | deletePermanently: deletePermanentlyProcedure(), 11 | }); 12 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/pages/deletion/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { deleteProcedure } from './delete'; 4 | import { deletePermanentlyProcedure } from './delete-permanently'; 5 | import { restoreProcedure } from './restore'; 6 | 7 | export const deletionRouter = trpc.router({ 8 | delete: deleteProcedure(), 9 | restore: restoreProcedure(), 10 | deletePermanently: deletePermanentlyProcedure(), 11 | }); 12 | -------------------------------------------------------------------------------- /apps/client/src/pages/pages/Group.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 20 | -------------------------------------------------------------------------------- /apps/client/src/code/pages/composables/use-key-state-tracking.ts: -------------------------------------------------------------------------------- 1 | import { useEventListener } from '@vueuse/core'; 2 | 3 | export const keyDown: Record = reactive({}); 4 | 5 | export function useKeyStateTracking() { 6 | useEventListener('keydown', (event) => (keyDown[event.key] = true), { 7 | capture: true, 8 | }); 9 | 10 | useEventListener('keyup', (event) => delete keyDown[event.key], { 11 | capture: true, 12 | }); 13 | } 14 | -------------------------------------------------------------------------------- /packages/@stdlib/nestjs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@deeplib/tsconfig/base.json", 3 | 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | 7 | "rootDir": "src", 8 | "outDir": "dist", 9 | 10 | "paths": { 11 | "src/*": ["src/*"] 12 | } 13 | }, 14 | 15 | "include": ["src/**/*.ts"], 16 | 17 | "tsc-alias": { 18 | "replacers": { 19 | "base-url": { 20 | "enabled": false 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/is-public.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const isPublic: DataField = { 5 | cacheLocally: true, // Reason: Performance (Field is used frequently) 6 | notifyUpdates: true, 7 | 8 | userGettable: () => true, 9 | 10 | columns: ['access_keyring'], 11 | 12 | get: ({ model }) => model?.access_keyring != null, 13 | }; 14 | -------------------------------------------------------------------------------- /packages/@stdlib/redlock/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@deeplib/tsconfig/base.json", 3 | 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | 7 | "rootDir": "src", 8 | "outDir": "dist", 9 | 10 | "paths": { 11 | "src/*": ["src/*"] 12 | } 13 | }, 14 | 15 | "include": ["src/**/*.ts"], 16 | 17 | "tsc-alias": { 18 | "replacers": { 19 | "base-url": { 20 | "enabled": false 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /apps/client/src/vue-props.d.ts: -------------------------------------------------------------------------------- 1 | import 'vue'; 2 | 3 | import type { DeepNotesInternals } from './boot/internals.universal'; 4 | 5 | declare module 'vue' { 6 | interface ComponentCustomProperties { 7 | global: typeof globalThis; 8 | internals: DeepNotesInternals; 9 | 10 | api: typeof api; 11 | 12 | appStore: typeof appStore; 13 | authStore: typeof authStore; 14 | uiStore: typeof uiStore; 15 | pagesStore: typeof pagesStore; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/session.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | 3 | export class SessionModel extends Model { 4 | static override tableName = 'sessions'; 5 | 6 | id!: string; 7 | 8 | user_id!: string; 9 | device_id!: string; 10 | 11 | encryption_key!: Uint8Array; 12 | 13 | refresh_code!: string; 14 | 15 | invalidated!: boolean; 16 | 17 | creation_date!: Date; 18 | last_refresh_date!: Date; 19 | expiration_date!: Date; 20 | } 21 | -------------------------------------------------------------------------------- /apps/client/src/stores/auth.ts: -------------------------------------------------------------------------------- 1 | import { defineStore } from 'pinia'; 2 | 3 | export const useAuthStore = defineStore('auth', () => { 4 | const state = reactive({ 5 | loggedIn: false, 6 | 7 | userId: '', 8 | sessionId: '', 9 | 10 | oldSessionKey: '', 11 | newSessionKey: '', 12 | 13 | redirect: ref(''), 14 | }); 15 | 16 | return { 17 | ...toRefs(state), 18 | }; 19 | }); 20 | 21 | export type AuthStore = ReturnType; 22 | -------------------------------------------------------------------------------- /apps/client/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'tsup'; 2 | 3 | export default defineConfig({ 4 | clean: false, // Clean output directory before each build 5 | entry: ['dist/ssr/index.js'], 6 | outDir: 'dist/ssr', 7 | outExtension({ format }: any) { 8 | return { js: `.${format}` }; 9 | }, 10 | format: ['cjs'], 11 | minify: true, 12 | sourcemap: false, 13 | splitting: false, 14 | dts: false, 15 | noExternal: [/^(@deeplib|@stdlib)\/.+$/], 16 | }); 17 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group-member/encrypted-access-keyring.ts: -------------------------------------------------------------------------------- 1 | import type { GroupMemberModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | import { splitStr } from '@stdlib/misc'; 4 | 5 | export const encryptedAccessKeyring: DataField = { 6 | notifyUpdates: true, 7 | 8 | userGettable: ({ userId, suffix }) => userId === splitStr(suffix, ':', 2)[1], 9 | 10 | columns: ['encrypted_access_keyring'], 11 | }; 12 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/group-join-request.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | 3 | export class GroupJoinRequestModel extends Model { 4 | static override tableName = 'group_join_requests'; 5 | 6 | static override idColumn = ['group_id', 'user_id']; 7 | 8 | group_id!: string; 9 | user_id!: string; 10 | 11 | encrypted_name!: Uint8Array; 12 | encrypted_name_for_user!: Uint8Array; 13 | 14 | rejected!: boolean; 15 | 16 | creation_date!: Date; 17 | } 18 | -------------------------------------------------------------------------------- /packages/@stdlib/base64/src/bytes-to-base64.ts: -------------------------------------------------------------------------------- 1 | import { Base64 } from 'js-base64'; 2 | 3 | export function bytesToBase64( 4 | input: Uint8Array, 5 | params?: { urlSafe?: boolean; padding?: boolean }, 6 | ): string { 7 | let result = Base64.fromUint8Array( 8 | new Uint8Array(input), 9 | params?.urlSafe ?? true, 10 | ); 11 | 12 | if (!params?.urlSafe && !params?.padding) { 13 | result = result.replace(/=+$/, ''); 14 | } 15 | 16 | return result; 17 | } 18 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/router.ts: -------------------------------------------------------------------------------- 1 | import { groupsRouter } from './api/groups'; 2 | import { pagesRouter } from './api/pages'; 3 | import { sessionsRouter } from './api/sessions'; 4 | import { usersRouter } from './api/users'; 5 | import { trpc } from './server'; 6 | 7 | export const appRouter = trpc.router({ 8 | users: usersRouter, 9 | sessions: sessionsRouter, 10 | groups: groupsRouter, 11 | pages: pagesRouter, 12 | }); 13 | 14 | export type AppRouter = typeof appRouter; 15 | -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/pages/backlinks/create.ts: -------------------------------------------------------------------------------- 1 | export async function createPageBacklink(input: { 2 | sourcePageId: string; 3 | targetUrl: string; 4 | }) { 5 | const pageLinkMatch = input.targetUrl.match(/\/pages\/([\w-]{21})(?:$|\/)/); 6 | 7 | if (pageLinkMatch == null) { 8 | return; 9 | } 10 | 11 | await trpcClient.pages.backlinks.create.mutate({ 12 | sourcePageId: input.sourcePageId, 13 | targetPageId: pageLinkMatch[1], 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /apps/realtime-server/src/index.ts: -------------------------------------------------------------------------------- 1 | import './env'; 2 | 3 | import { mainLogger } from '@stdlib/misc'; 4 | import { httpServer } from 'src/http-server'; 5 | 6 | import { initKnex } from './data/knex'; 7 | 8 | const moduleLogger = mainLogger.sub('index.ts'); 9 | 10 | initKnex(); 11 | 12 | httpServer().listen(parseInt(process.env.REALTIME_SERVER_PORT), () => { 13 | moduleLogger.info( 14 | `realtime-server started on port ${process.env.REALTIME_SERVER_PORT}`, 15 | ); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group-member/encrypted-internal-keyring.ts: -------------------------------------------------------------------------------- 1 | import type { GroupMemberModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | import { splitStr } from '@stdlib/misc'; 4 | 5 | export const encryptedInternalKeyring: DataField = { 6 | notifyUpdates: true, 7 | 8 | userGettable: ({ userId, suffix }) => userId === splitStr(suffix, ':', 2)[1], 9 | 10 | columns: ['encrypted_internal_keyring'], 11 | }; 12 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/sessions/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { loginProcedure } from './login'; 4 | import { logoutProcedure } from './logout'; 5 | import { refreshProcedure } from './refresh'; 6 | import { startDemoProcedure } from './start-demo'; 7 | 8 | export const sessionsRouter = trpc.router({ 9 | startDemo: startDemoProcedure(), 10 | login: loginProcedure(), 11 | refresh: refreshProcedure(), 12 | logout: logoutProcedure(), 13 | }); 14 | -------------------------------------------------------------------------------- /apps/client/src/shims-vue.d.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | 3 | /// 4 | /// 5 | 6 | // Mocks all files ending in `.vue` showing them as plain Vue instances 7 | declare module '*.vue' { 8 | import type { DefineComponent } from 'vue' 9 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types 10 | const component: DefineComponent<{}, {}, any> 11 | export default component 12 | } 13 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/page/exists.ts: -------------------------------------------------------------------------------- 1 | import type { PageModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const exists: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: () => true, 8 | 9 | columns: ['id', 'permanent_deletion_date'], 10 | 11 | get: ({ model }) => 12 | model?.id != null && 13 | (model.permanent_deletion_date == null || 14 | model.permanent_deletion_date > new Date()), 15 | }; 16 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group-join-request/encrypted-name-for-user.ts: -------------------------------------------------------------------------------- 1 | import type { GroupJoinRequestModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | import { splitStr } from '@stdlib/misc'; 4 | 5 | export const encryptedNameForUser: DataField = { 6 | notifyUpdates: true, 7 | 8 | userGettable: async ({ userId, suffix }) => 9 | userId === splitStr(suffix, ':', 2)[1], 10 | 11 | columns: ['encrypted_name_for_user'], 12 | }; 13 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/exists.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | export const exists: DataField = { 5 | notifyUpdates: true, 6 | 7 | userGettable: () => true, 8 | 9 | columns: ['id', 'permanent_deletion_date'], 10 | 11 | get: ({ model }) => 12 | model?.id != null && 13 | (model.permanent_deletion_date == null || 14 | model.permanent_deletion_date > new Date()), 15 | }; 16 | -------------------------------------------------------------------------------- /apps/client/src/code/pages/page/elems/elems.ts: -------------------------------------------------------------------------------- 1 | import type { Page } from '../page'; 2 | 3 | export class PageElems { 4 | readonly page: Page; 5 | 6 | constructor(input: { page: Page }) { 7 | this.page = input.page; 8 | } 9 | 10 | setup() { 11 | this.page.notes.createAndObserveIds(this.page.react.collab.noteIds); 12 | this.page.notes.observeMap(); 13 | 14 | this.page.arrows.createAndObserveIds(this.page.react.collab.arrowIds); 15 | this.page.arrows.observeMap(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group-join-invitation/encrypted-name-for-user.ts: -------------------------------------------------------------------------------- 1 | import type { GroupJoinInvitationModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | import { splitStr } from '@stdlib/misc'; 4 | 5 | export const encryptedNameForUser: DataField = { 6 | notifyUpdates: true, 7 | 8 | userGettable: async ({ userId, suffix }) => 9 | userId === splitStr(suffix, ':', 2)[1], 10 | 11 | columns: ['encrypted_name_for_user'], 12 | }; 13 | -------------------------------------------------------------------------------- /apps/client/src/boot/vue.universal.ts: -------------------------------------------------------------------------------- 1 | import { boot } from 'quasar/wrappers'; 2 | 3 | export default boot(async ({ app }) => { 4 | app.config.unwrapInjectedRef = true; 5 | 6 | app.config.globalProperties.global = globalThis; 7 | app.config.globalProperties.internals = internals; 8 | 9 | app.config.globalProperties.appStore = appStore; 10 | app.config.globalProperties.authStore = authStore; 11 | app.config.globalProperties.uiStore = uiStore; 12 | app.config.globalProperties.pagesStore = pagesStore; 13 | }); 14 | -------------------------------------------------------------------------------- /apps/client/src/code/pages/composables/use-touchscreen-pointer-capture-release.ts: -------------------------------------------------------------------------------- 1 | import { useEventListener } from '@vueuse/core'; 2 | 3 | export function useTouchscreenPointerCaptureRelease() { 4 | useEventListener( 5 | 'pointerdown', 6 | (event) => { 7 | mainLogger 8 | .sub('useTouchscreenPointerCaptureRelease') 9 | .info('Release pointer capture'); 10 | 11 | (event.target as Element).releasePointerCapture(event.pointerId); 12 | }, 13 | { capture: true }, 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/index.ts: -------------------------------------------------------------------------------- 1 | export * from './device'; 2 | export * from './group'; 3 | export * from './group-join-invitation'; 4 | export * from './group-join-request'; 5 | export * from './group-member'; 6 | export * from './notification'; 7 | export * from './page'; 8 | export * from './page-link'; 9 | export * from './page-snapshot'; 10 | export * from './page-update'; 11 | export * from './session'; 12 | export * from './user'; 13 | export * from './user-notification'; 14 | export * from './user-page'; 15 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@deeplib/tsconfig/base.json", 3 | 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | 7 | "rootDir": "src", 8 | "outDir": "dist", 9 | 10 | "paths": { 11 | "src/*": ["src/*"], 12 | 13 | "@stdlib/*": ["../../../packages/@stdlib/*/src"] 14 | } 15 | }, 16 | 17 | "include": ["src/**/*.ts"], 18 | 19 | "tsc-alias": { 20 | "replacers": { 21 | "base-url": { 22 | "enabled": false 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /apps/client/src/code/utils/zxcvbn.ts: -------------------------------------------------------------------------------- 1 | import { zxcvbnOptions } from '@zxcvbn-ts/core'; 2 | import * as zxcvbnCommonPackage from '@zxcvbn-ts/language-common'; 3 | import * as zxcvbnEnPackage from '@zxcvbn-ts/language-en'; 4 | export { zxcvbn } from '@zxcvbn-ts/core'; 5 | 6 | zxcvbnOptions.setOptions({ 7 | translations: zxcvbnEnPackage.translations, 8 | 9 | graphs: zxcvbnCommonPackage.adjacencyGraphs, 10 | 11 | dictionary: { 12 | ...zxcvbnCommonPackage.dictionary, 13 | ...zxcvbnEnPackage.dictionary, 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayNonFreePageScreen.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 17 | -------------------------------------------------------------------------------- /apps/client/src/layouts/PagesLayout/MainToolbar/Notifications/NotificationsBtn.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 19 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/capacitor.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "appId": "app.deepnotes", 3 | "appName": "DeepNotes", 4 | "bundledWebRuntime": false, 5 | "npmClient": "pnpm", 6 | "webDir": "www", 7 | "server": { 8 | "hostname": "deepnotes.app", 9 | "iosScheme": "https", 10 | "androidScheme": "https" 11 | }, 12 | "plugins": { 13 | "CapacitorCookies": { 14 | "enabled": true 15 | }, 16 | "SplashScreen": { 17 | "launchShowDuration": 2000, 18 | "backgroundColor": "#181818" 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/permanent-deletion-date.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | import { userHasPermission } from '../../roles'; 5 | 6 | export const permanentDeletionDate: DataField = { 7 | notifyUpdates: true, 8 | 9 | userGettable: async ({ userId, suffix: groupId, dataAbstraction }) => 10 | await userHasPermission(dataAbstraction, userId, groupId, 'viewGroupPages'), 11 | 12 | columns: ['permanent_deletion_date'], 13 | }; 14 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/page-snapshot.ts: -------------------------------------------------------------------------------- 1 | import type { PageSnapshotType } from '@deeplib/misc'; 2 | import { Model } from 'objection'; 3 | 4 | export class PageSnapshotModel extends Model { 5 | static override tableName = 'page_snapshots'; 6 | 7 | static override idColumn = ['id']; 8 | 9 | id!: string; 10 | 11 | page_id!: string; 12 | 13 | creation_date!: Date; 14 | 15 | author_id!: string; 16 | 17 | encrypted_symmetric_key!: Uint8Array; 18 | encrypted_data!: Uint8Array; 19 | 20 | type!: PageSnapshotType; 21 | } 22 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turborepo.org/schema.json", 3 | "pipeline": { 4 | "npkill": { "cache": false }, 5 | "dev": { "cache": false }, 6 | "lint": { "outputs": [] }, 7 | "fix": { "cache": false }, 8 | "test": { "outputs": [] }, 9 | "build": { 10 | "dependsOn": ["^build"], 11 | "outputs": ["dist/**"] 12 | }, 13 | "build:watch": { "cache": false }, 14 | "repo:build": { "cache": false }, 15 | "repo:build:watch": { "cache": false }, 16 | "clean": { "cache": false } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/users/delete-account.ts: -------------------------------------------------------------------------------- 1 | import { deriveUserValues } from 'src/code/crypto'; 2 | 3 | export async function deleteAccount(input: { password: string }) { 4 | const email = await internals.realtime.hget( 5 | 'user', 6 | authStore().userId, 7 | 'email', 8 | ); 9 | const derivedUserValues = await deriveUserValues({ 10 | email, 11 | password: input.password, 12 | }); 13 | 14 | await trpcClient.users.account.delete.mutate({ 15 | loginHash: derivedUserValues.loginHash, 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /apps/client/src/components/TabBtn.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 23 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/encrypted-content-keyring.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | import { userHasPermission } from '../../roles'; 5 | 6 | export const encryptedContentKeyring: DataField = { 7 | notifyUpdates: true, 8 | 9 | userGettable: async ({ userId, suffix: groupId, dataAbstraction }) => 10 | await userHasPermission(dataAbstraction, userId, groupId, 'viewGroupPages'), 11 | 12 | columns: ['encrypted_content_keyring'], 13 | }; 14 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/group/encrypted-private-keyring.ts: -------------------------------------------------------------------------------- 1 | import type { GroupModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | import { userHasPermission } from '../../roles'; 5 | 6 | export const encryptedPrivateKeyring: DataField = { 7 | notifyUpdates: true, 8 | 9 | userGettable: async ({ userId, suffix: groupId, dataAbstraction }) => 10 | await userHasPermission(dataAbstraction, userId, groupId, 'viewGroupPages'), 11 | 12 | columns: ['encrypted_private_keyring'], 13 | }; 14 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.bracketPairColorization.enabled": true, 3 | "editor.guides.bracketPairs": true, 4 | "editor.formatOnSave": true, 5 | "editor.defaultFormatter": "esbenp.prettier-vscode", 6 | "editor.codeActionsOnSave": ["source.fixAll.eslint"], 7 | "eslint.validate": ["javascript", "typescript"], 8 | "typescript.tsdk": "node_modules/typescript/lib", 9 | "vue.features.codeActions.enable": false, 10 | "java.configuration.updateBuildConfiguration": "interactive", 11 | "testing.automaticallyOpenPeekView": "never" 12 | } 13 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/pages/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { backlinksRouter } from './backlinks'; 4 | import { bumpProcedure } from './bump'; 5 | import { createProcedure } from './create'; 6 | import { deletionRouter } from './deletion'; 7 | import { snapshotsRouter } from './snapshots'; 8 | 9 | export const pagesRouter = trpc.router({ 10 | create: createProcedure(), 11 | bump: bumpProcedure(), 12 | 13 | backlinks: backlinksRouter, 14 | snapshots: snapshotsRouter, 15 | 16 | deletion: deletionRouter, 17 | }); 18 | -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/users/add-favorite-pages.ts: -------------------------------------------------------------------------------- 1 | import { pluralS } from '@stdlib/misc'; 2 | import { handleError } from 'src/code/utils/misc'; 3 | 4 | export async function addFavoritePages(pageIds: string[]) { 5 | try { 6 | await trpcClient.users.pages.addFavoritePages.mutate({ 7 | pageIds: pageIds, 8 | }); 9 | 10 | $quasar().notify({ 11 | message: `Page${pluralS(pageIds.length)} added to favorites.`, 12 | color: 'positive', 13 | }); 14 | } catch (error) { 15 | handleError(error); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/math.ts: -------------------------------------------------------------------------------- 1 | export function lerp(a: number, b: number, t: number) { 2 | return a + (b - a) * t; 3 | } 4 | 5 | export function map( 6 | value: number, 7 | inMin: number, 8 | inMax: number, 9 | outMin: number, 10 | outMax: number, 11 | ) { 12 | return lerp(outMin, outMax, (value - inMin) / (inMax - inMin)); 13 | } 14 | 15 | export function minmax(value: number, min: number, max: number) { 16 | return Math.min(Math.max(value, min), max); 17 | } 18 | 19 | export function posMod(n, m) { 20 | return ((n % m) + m) % m; 21 | } 22 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/test/java/com/getcapacitor/myapp/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package com.getcapacitor.myapp; 2 | 3 | import static org.junit.Assert.*; 4 | 5 | import org.junit.Test; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | 14 | @Test 15 | public void addition_isCorrect() throws Exception { 16 | assertEquals(4, 2 + 2); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/metadata/en-US/description.txt: -------------------------------------------------------------------------------- 1 | Why DeepNotes? 2 | - Infinite canvases: Free yourself from the big wall of text. 3 | - Deep page nesting: Explore concepts in all their complexity. 4 | - End-to-end encryption: Keep your notes well protected. 5 | - Realtime collaboration: Create groups to collaborate with your teams. 6 | - Flexible note system: Organize your notes in whatever way you want. 7 | - Lifelong storage: Never lose your notes ever again. 8 | 9 | Terms of Use: https://www.apple.com/legal/internet-services/itunes/dev/stdeula/ 10 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/pages/get-starting-page-id.ts: -------------------------------------------------------------------------------- 1 | import { once } from 'lodash'; 2 | import type { InferProcedureOpts } from 'src/trpc/helpers'; 3 | import { authProcedure } from 'src/trpc/helpers'; 4 | 5 | const baseProcedure = authProcedure; 6 | 7 | export const getStartingPageIdProcedure = once(() => 8 | baseProcedure.query(getStartingPageId), 9 | ); 10 | 11 | export async function getStartingPageId({ 12 | ctx, 13 | }: InferProcedureOpts) { 14 | return await ctx.dataAbstraction.hget('user', ctx.userId, 'starting-page-id'); 15 | } 16 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "splash-2732x2732-2.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "splash-2732x2732-1.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "splash-2732x2732.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /apps/client/src-capacitor/ios/App/fastlane/Matchfile: -------------------------------------------------------------------------------- 1 | git_url("git@github.com:DeepNotesApp/FastlaneMatch") 2 | 3 | storage_mode("git") 4 | 5 | type("development") # The default type, can be: appstore, adhoc, enterprise or development 6 | 7 | app_identifier(["app.deepnotes"]) 8 | username("gustavottoyota@gmail.com") # Your Apple Developer Portal username 9 | 10 | # For all available options run `fastlane match --help` 11 | # Remove the # in the beginning of the line to enable the other options 12 | 13 | # The docs are available on https://docs.fastlane.tools/actions/match 14 | -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/users/remove-favorite-pages.ts: -------------------------------------------------------------------------------- 1 | import { pluralS } from '@stdlib/misc'; 2 | import { handleError } from 'src/code/utils/misc'; 3 | 4 | export async function removeFavoritePages(pageIds: string[]) { 5 | try { 6 | await trpcClient.users.pages.removeFavoritePages.mutate({ 7 | pageIds: pageIds, 8 | }); 9 | 10 | $quasar().notify({ 11 | message: `Page${pluralS(pageIds.length)} removed from favorites.`, 12 | color: 'negative', 13 | }); 14 | } catch (error) { 15 | handleError(error); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /apps/client/src/code/pages/computed/page-group-id.ts: -------------------------------------------------------------------------------- 1 | import { createSmartComputedDict } from '@stdlib/vue'; 2 | import { once } from 'lodash'; 3 | 4 | export const pageGroupIds = once(() => 5 | createSmartComputedDict({ 6 | get: async (pageId) => { 7 | if (pageId == null) { 8 | return; 9 | } 10 | 11 | const groupId = await internals.realtime.globalCtx.hgetAsync( 12 | 'page', 13 | pageId, 14 | 'group-id', 15 | ); 16 | 17 | return groupId; 18 | }, 19 | 20 | defaultValue: undefined, 21 | }), 22 | ); 23 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/assets/capacitor.plugins.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "pkg": "@capacitor/app", 4 | "classpath": "com.capacitorjs.plugins.app.AppPlugin" 5 | }, 6 | { 7 | "pkg": "@capacitor/clipboard", 8 | "classpath": "com.capacitorjs.plugins.clipboard.ClipboardPlugin" 9 | }, 10 | { 11 | "pkg": "@capacitor/splash-screen", 12 | "classpath": "com.capacitorjs.plugins.splashscreen.SplashScreenPlugin" 13 | }, 14 | { 15 | "pkg": "@revenuecat/purchases-capacitor", 16 | "classpath": "com.revenuecat.purchases.capacitor.PurchasesPlugin" 17 | } 18 | ] 19 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/user/email.ts: -------------------------------------------------------------------------------- 1 | import type { UserModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | import { decryptUserEmail, encryptUserEmail } from '../../emails'; 5 | 6 | export const email: DataField = { 7 | notifyUpdates: true, 8 | 9 | userGettable: ({ userId, suffix }) => userId === suffix, 10 | 11 | columns: ['encrypted_email'], 12 | 13 | get: ({ model }) => decryptUserEmail(model?.encrypted_email!), 14 | set: ({ model, value }) => (model.encrypted_email = encryptUserEmail(value)), 15 | }; 16 | -------------------------------------------------------------------------------- /apps/client/src/stores/index.ts: -------------------------------------------------------------------------------- 1 | import { createPinia } from 'pinia'; 2 | import { store } from 'quasar/wrappers'; 3 | 4 | /* 5 | * If not building with SSR mode, you can 6 | * directly export the Store instantiation; 7 | * 8 | * The function below can be async too; either use 9 | * async/await or return a Promise which resolves 10 | * with the Store instance. 11 | */ 12 | 13 | export default store((/* { ssrContext } */) => { 14 | const pinia = createPinia(); 15 | 16 | // You can add Pinia plugins here 17 | // pinia.use(SomePiniaPlugin) 18 | 19 | return pinia; 20 | }); 21 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@deepnotes/client-capacitor", 3 | "description": "DeepNotes", 4 | "version": "1.0.14", 5 | "author": "Gustavo Toyota ", 6 | "dependencies": { 7 | "@capacitor/android": "^5.5.1", 8 | "@capacitor/app": "^5.0.6", 9 | "@capacitor/cli": "^5.5.1", 10 | "@capacitor/clipboard": "^5.0.6", 11 | "@capacitor/core": "^5.5.1", 12 | "@capacitor/ios": "^5.5.1", 13 | "@capacitor/splash-screen": "^5.0.6", 14 | "@revenuecat/purchases-capacitor": "^7.1.1" 15 | }, 16 | "private": true 17 | } -------------------------------------------------------------------------------- /apps/scheduler/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16 AS builder 2 | 3 | RUN npm install -g pnpm@^8.0.0 4 | 5 | WORKDIR /build 6 | COPY ./ ./ 7 | RUN pnpm install --filter deepnotes --filter @deepnotes/scheduler... 8 | RUN pnpm --filter @deepnotes/scheduler run bundle 9 | 10 | FROM node:16-alpine AS runner 11 | 12 | RUN npm install -g pnpm@^8.0.0 13 | RUN mkdir /usr/local/pnpm 14 | ENV PNPM_HOME="/usr/local/pnpm" 15 | ENV PATH="${PATH}:/usr/local/pnpm" 16 | 17 | WORKDIR /app 18 | COPY --from=builder /build/apps/scheduler/dist/ ./ 19 | RUN pnpm init 20 | RUN pnpm install knex ws pg 21 | CMD node /app/index.js -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/group-member.ts: -------------------------------------------------------------------------------- 1 | import type { GroupRoleID } from '@deeplib/misc'; 2 | import { Model } from 'objection'; 3 | 4 | export class GroupMemberModel extends Model { 5 | static override tableName = 'group_members'; 6 | 7 | static override idColumn = ['group_id', 'user_id']; 8 | 9 | group_id!: string; 10 | user_id!: string; 11 | 12 | role!: GroupRoleID; 13 | 14 | encrypted_access_keyring!: Uint8Array | null; 15 | encrypted_internal_keyring!: Uint8Array; 16 | 17 | encrypted_name!: Uint8Array | null; 18 | 19 | last_activity_date!: Date; 20 | } 21 | -------------------------------------------------------------------------------- /packages/@deeplib/misc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | 4 | "extends": "@deeplib/tsconfig/base.json", 5 | 6 | "compilerOptions": { 7 | "types": ["vitest/globals"], 8 | 9 | "baseUrl": ".", 10 | 11 | "rootDir": "src", 12 | "outDir": "dist", 13 | 14 | "paths": { 15 | "src/*": ["src/*"], 16 | 17 | "@stdlib/*": ["../../../packages/@stdlib/*/src"] 18 | } 19 | }, 20 | 21 | "references": [{ "path": "../../../packages/@stdlib/misc/tsconfig.json" }], 22 | 23 | "include": ["*.ts", "src/**/*.ts"] 24 | } 25 | -------------------------------------------------------------------------------- /apps/client/src/code/pages/composables/use-middle-click-paste-prevention.ts: -------------------------------------------------------------------------------- 1 | import { useEventListener } from '@vueuse/core'; 2 | 3 | export function useMiddleClickPastePrevention() { 4 | useEventListener('auxclick', (event) => { 5 | if (event.button === 1) { 6 | mainLogger 7 | .sub('useMiddleClickPastePrevention') 8 | .info('Prevent middle click paste'); 9 | 10 | event.preventDefault(); 11 | } 12 | }); 13 | 14 | useEventListener('pointerup', (event) => { 15 | if (event.button === 1) { 16 | event.preventDefault(); 17 | } 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayProPlanRequiredScreen.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 19 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/variables.gradle: -------------------------------------------------------------------------------- 1 | ext { 2 | minSdkVersion = 22 3 | compileSdkVersion = 33 4 | targetSdkVersion = 33 5 | androidxActivityVersion = '1.7.0' 6 | androidxAppCompatVersion = '1.6.1' 7 | androidxCoordinatorLayoutVersion = '1.2.0' 8 | androidxCoreVersion = '1.10.0' 9 | androidxFragmentVersion = '1.5.6' 10 | coreSplashScreenVersion = '1.0.0' 11 | androidxWebkitVersion = '1.6.1' 12 | junitVersion = '4.13.2' 13 | androidxJunitVersion = '1.1.5' 14 | androidxEspressoCoreVersion = '3.5.1' 15 | cordovaAndroidVersion = '10.1.1' 16 | } -------------------------------------------------------------------------------- /packages/@stdlib/base64/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@deeplib/tsconfig/base.json", 3 | 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | 7 | "rootDir": "src", 8 | "outDir": "dist", 9 | 10 | "paths": { 11 | "src/*": ["src/*"], 12 | 13 | "@stdlib/*": ["../../../packages/@stdlib/*/src"] 14 | } 15 | }, 16 | 17 | "references": [{ "path": "../../../packages/@stdlib/misc/tsconfig.json" }], 18 | 19 | "include": ["src/**/*.ts"], 20 | 21 | "tsc-alias": { 22 | "replacers": { 23 | "base-url": { 24 | "enabled": false 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /apps/client/src/code/areas/tiptap/image-resize/extension.ts: -------------------------------------------------------------------------------- 1 | import Image from '@tiptap/extension-image'; 2 | import { VueNodeViewRenderer } from '@tiptap/vue-3'; 3 | 4 | import NodeView from './NodeView.vue'; 5 | 6 | export const ImageResizeExtension = Image.extend({ 7 | addAttributes() { 8 | return { 9 | ...this.parent?.(), 10 | 11 | width: { 12 | default: undefined, 13 | renderHTML: (attribs) => ({ 14 | width: attribs.width, 15 | }), 16 | }, 17 | }; 18 | }, 19 | 20 | addNodeView() { 21 | return VueNodeViewRenderer(NodeView); 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /apps/manager/src/env.ts: -------------------------------------------------------------------------------- 1 | import { once } from '@stdlib/misc'; 2 | import dotenv from 'dotenv'; 3 | import * as dotenvExpand from 'dotenv-expand'; 4 | 5 | Object.defineProperty(process, 'env', { 6 | get: once(() => { 7 | dotenvExpand.expand( 8 | dotenv.config({ path: '../../.env' }).parsed?.DEV 9 | ? dotenv.config({ path: '../../.env' }).parsed?.PRODEV 10 | ? dotenv.config({ path: '../../.env.prodev' }) 11 | : dotenv.config({ path: '../../.env.dev' }) 12 | : dotenv.config({ path: '../../.env.prod' }), 13 | ); 14 | 15 | return process.env; 16 | }, process.env), 17 | }); 18 | -------------------------------------------------------------------------------- /packages/@deeplib/misc/src/tokens.ts: -------------------------------------------------------------------------------- 1 | export interface AccessTokenPayload { 2 | uid: string; 3 | sid: string; 4 | } 5 | 6 | export interface RefreshTokenPayload { 7 | sid: string; 8 | rfc: string; 9 | rms: boolean; 10 | } 11 | 12 | export const ACCESS_TOKEN_DURATION = 30 * 60 * 1000; 13 | export const REFRESH_TOKEN_SHORT_DURATION = 60 * 60 * 1000; 14 | export const REFRESH_TOKEN_LONG_DURATION = 7 * 24 * 60 * 60 * 1000; 15 | 16 | export function getRefreshTokenExpiration(rememberSession: boolean) { 17 | return rememberSession 18 | ? REFRESH_TOKEN_LONG_DURATION 19 | : REFRESH_TOKEN_SHORT_DURATION; 20 | } 21 | -------------------------------------------------------------------------------- /apps/app-server/src/env.ts: -------------------------------------------------------------------------------- 1 | import { once } from '@stdlib/misc'; 2 | import dotenv from 'dotenv'; 3 | import * as dotenvExpand from 'dotenv-expand'; 4 | 5 | Object.defineProperty(process, 'env', { 6 | get: once(() => { 7 | dotenvExpand.expand( 8 | dotenv.config({ path: '../../.env' }).parsed?.DEV 9 | ? dotenv.config({ path: '../../.env' }).parsed?.PRODEV 10 | ? dotenv.config({ path: '../../.env.prodev' }) 11 | : dotenv.config({ path: '../../.env.dev' }) 12 | : dotenv.config({ path: '../../.env.prod' }), 13 | ); 14 | 15 | return process.env; 16 | }, process.env), 17 | }); 18 | -------------------------------------------------------------------------------- /apps/collab-server/src/env.ts: -------------------------------------------------------------------------------- 1 | import { once } from '@stdlib/misc'; 2 | import dotenv from 'dotenv'; 3 | import * as dotenvExpand from 'dotenv-expand'; 4 | 5 | Object.defineProperty(process, 'env', { 6 | get: once(() => { 7 | dotenvExpand.expand( 8 | dotenv.config({ path: '../../.env' }).parsed?.DEV 9 | ? dotenv.config({ path: '../../.env' }).parsed?.PRODEV 10 | ? dotenv.config({ path: '../../.env.prodev' }) 11 | : dotenv.config({ path: '../../.env.dev' }) 12 | : dotenv.config({ path: '../../.env.prod' }), 13 | ); 14 | 15 | return process.env; 16 | }, process.env), 17 | }); 18 | -------------------------------------------------------------------------------- /apps/scheduler/src/env.ts: -------------------------------------------------------------------------------- 1 | import { once } from '@stdlib/misc'; 2 | import dotenv from 'dotenv'; 3 | import * as dotenvExpand from 'dotenv-expand'; 4 | 5 | Object.defineProperty(process, 'env', { 6 | get: once(() => { 7 | dotenvExpand.expand( 8 | dotenv.config({ path: '../../.env' }).parsed?.DEV 9 | ? dotenv.config({ path: '../../.env' }).parsed?.PRODEV 10 | ? dotenv.config({ path: '../../.env.prodev' }) 11 | : dotenv.config({ path: '../../.env.dev' }) 12 | : dotenv.config({ path: '../../.env.prod' }), 13 | ); 14 | 15 | return process.env; 16 | }, process.env), 17 | }); 18 | -------------------------------------------------------------------------------- /apps/realtime-server/src/env.ts: -------------------------------------------------------------------------------- 1 | import { once } from '@stdlib/misc'; 2 | import dotenv from 'dotenv'; 3 | import * as dotenvExpand from 'dotenv-expand'; 4 | 5 | Object.defineProperty(process, 'env', { 6 | get: once(() => { 7 | dotenvExpand.expand( 8 | dotenv.config({ path: '../../.env' }).parsed?.DEV 9 | ? dotenv.config({ path: '../../.env' }).parsed?.PRODEV 10 | ? dotenv.config({ path: '../../.env.prodev' }) 11 | : dotenv.config({ path: '../../.env.dev' }) 12 | : dotenv.config({ path: '../../.env.prod' }), 13 | ); 14 | 15 | return process.env; 16 | }, process.env), 17 | }); 18 | -------------------------------------------------------------------------------- /apps/client/src/components/Checkbox.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 20 | 21 | 30 | -------------------------------------------------------------------------------- /apps/client/src/pages/home/Help/Pages/SubscriptionExpiration.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 20 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/page/permanent-deletion-date.ts: -------------------------------------------------------------------------------- 1 | import type { PageModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | import { userHasPermission } from '../../roles'; 5 | 6 | export const permanentDeletionDate: DataField = { 7 | notifyUpdates: true, 8 | 9 | userGettable: async ({ userId, suffix: pageId, dataAbstraction }) => 10 | await userHasPermission( 11 | dataAbstraction, 12 | userId, 13 | await dataAbstraction.hget('page', pageId, 'group-id'), 14 | 'viewGroupPages', 15 | ), 16 | 17 | columns: ['permanent_deletion_date'], 18 | }; 19 | -------------------------------------------------------------------------------- /packages/@deeplib/mail/src/send-grid.ts: -------------------------------------------------------------------------------- 1 | import SendGridMail from '@sendgrid/mail'; 2 | import { iif } from '@stdlib/misc'; 3 | import { once } from 'lodash'; 4 | 5 | import type { MailOptions } from '.'; 6 | 7 | const _getSendGridMail = once(() => { 8 | SendGridMail.setApiKey(process.env.SENDGRID_API_KEY); 9 | 10 | return SendGridMail; 11 | }); 12 | 13 | export async function sendSendGridMail({ 14 | from, 15 | to, 16 | subject, 17 | html, 18 | }: MailOptions) { 19 | await _getSendGridMail().send({ 20 | from, 21 | to, 22 | subject: iif(process.env.DEV, '[SendGrid] ', '') + subject, 23 | html, 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /apps/client/src-capacitor/android/app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /apps/client/src/code/areas/api-interface/groups/privacy/make-public.ts: -------------------------------------------------------------------------------- 1 | import { DataLayer } from '@stdlib/crypto'; 2 | import { groupAccessKeyrings } from 'src/code/pages/computed/group-access-keyrings'; 3 | 4 | export async function makeGroupPublic(input: { groupId: string }) { 5 | const accessKeyring = await groupAccessKeyrings()(input.groupId).getAsync(); 6 | 7 | if (accessKeyring?.topLayer !== DataLayer.Raw) { 8 | throw new Error('Invalid group keyring.'); 9 | } 10 | 11 | await trpcClient.groups.privacy.makePublic.mutate({ 12 | groupId: input.groupId, 13 | 14 | accessKeyring: accessKeyring.wrappedValue, 15 | }); 16 | } 17 | -------------------------------------------------------------------------------- /apps/client/src/components/Radio.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 20 | 21 | 30 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/page.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | 3 | export class PageModel extends Model { 4 | static override tableName = 'pages'; 5 | 6 | id!: string; 7 | 8 | encrypted_relative_title!: Uint8Array; 9 | encrypted_absolute_title!: Uint8Array; 10 | 11 | group_id!: string; 12 | 13 | creation_date!: Date; 14 | last_activity_date!: Date; 15 | 16 | encrypted_symmetric_keyring!: Uint8Array; 17 | 18 | free!: boolean; 19 | 20 | next_snapshot_date!: Date; 21 | next_snapshot_update_index!: number; 22 | 23 | next_key_rotation_date!: Date; 24 | 25 | permanent_deletion_date!: Date | null; 26 | } 27 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/logger.ts: -------------------------------------------------------------------------------- 1 | import { 2 | addInterval, 3 | addTimestamp, 4 | capitalizeField, 5 | colorizeField, 6 | ConsoleOutput, 7 | Logger, 8 | markSlot, 9 | writeTo, 10 | } from 'unilogr'; 11 | 12 | export const mainLogger = new Logger([ 13 | markSlot('filters'), 14 | 15 | capitalizeField('level'), 16 | colorizeField('level'), 17 | addTimestamp(), 18 | addInterval(), 19 | 20 | markSlot(), 21 | 22 | ({ timestamp, level, message, ctx, interval }) => 23 | `${timestamp} [${level}]${ 24 | ctx ? ` (${ctx})` : '' 25 | }: ${message} (${interval})`, 26 | 27 | writeTo(new ConsoleOutput()), 28 | ]); 29 | -------------------------------------------------------------------------------- /apps/collab-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16 AS builder 2 | 3 | RUN npm install -g pnpm@^8.0.0 4 | 5 | WORKDIR /build 6 | COPY ./ ./ 7 | RUN pnpm install --filter deepnotes --filter @deepnotes/collab-server... 8 | RUN pnpm --filter @deepnotes/collab-server run bundle 9 | 10 | FROM node:16-alpine AS runner 11 | 12 | RUN npm install -g pnpm@^8.0.0 13 | RUN mkdir /usr/local/pnpm 14 | ENV PNPM_HOME="/usr/local/pnpm" 15 | ENV PATH="${PATH}:/usr/local/pnpm" 16 | RUN pnpm add -g pm2 17 | 18 | WORKDIR /app 19 | COPY --from=builder /build/apps/collab-server/dist/ ./ 20 | RUN pnpm init 21 | RUN pnpm install knex ws pg 22 | CMD pm2 start /app/index.js -i max && pm2 logs -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/page/encrypted-symmetric-keyring.ts: -------------------------------------------------------------------------------- 1 | import type { PageModel } from '@deeplib/db'; 2 | import type { DataField } from '@stdlib/data'; 3 | 4 | import { userHasPermission } from '../../roles'; 5 | 6 | export const encryptedSymmetricKeyring: DataField = { 7 | notifyUpdates: true, 8 | 9 | userGettable: async ({ userId, suffix: pageId, dataAbstraction }) => 10 | await userHasPermission( 11 | dataAbstraction, 12 | userId, 13 | await dataAbstraction.hget('page', pageId, 'group-id'), 14 | 'viewGroupPages', 15 | ), 16 | 17 | columns: ['encrypted_symmetric_keyring'], 18 | }; 19 | -------------------------------------------------------------------------------- /packages/@stdlib/misc/src/uuid.ts: -------------------------------------------------------------------------------- 1 | export function isUuid4(text: string) { 2 | const pattern = 3 | /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i; 4 | 5 | return pattern.test(text); 6 | } 7 | 8 | export function uuidToBytes(uuid: string): Uint8Array { 9 | return new Uint8Array( 10 | (uuid.replace(/-/g, '').match(/.{2}/g) || []).map((b) => parseInt(b, 16)), 11 | ); 12 | } 13 | export function bytesToUUID(bytes: Uint8Array): string { 14 | return Array.from(bytes) 15 | .map((b) => ('00' + b.toString(16)).slice(-2)) 16 | .join('') 17 | .replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/, '$1-$2-$3-$4-$5'); 18 | } 19 | -------------------------------------------------------------------------------- /apps/app-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16 AS builder 2 | 3 | RUN npm install -g pnpm@^8.0.0 4 | 5 | WORKDIR /build 6 | COPY ./ ./ 7 | RUN pnpm install --filter deepnotes --filter @deepnotes/app-server... 8 | RUN pnpm --filter @deepnotes/app-server run bundle 9 | 10 | FROM node:16-alpine AS runner 11 | 12 | RUN npm install -g pnpm@^8.0.0 13 | RUN mkdir /usr/local/pnpm 14 | ENV PNPM_HOME="/usr/local/pnpm" 15 | ENV PATH="${PATH}:/usr/local/pnpm" 16 | RUN pnpm add -g pm2 17 | 18 | WORKDIR /app 19 | COPY --from=builder /build/apps/app-server/dist/ ./ 20 | RUN pnpm init 21 | RUN pnpm install knex ws pg @getbrevo/brevo 22 | CMD pm2 start /app/index.js -i max && pm2 logs -------------------------------------------------------------------------------- /apps/client/src/pages/home/Help/Pages/Roadmap.vue: -------------------------------------------------------------------------------- 1 | 19 | 20 | 27 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/group.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | 3 | export class GroupModel extends Model { 4 | static override tableName = 'groups'; 5 | 6 | id!: string; 7 | 8 | encrypted_name!: Uint8Array; 9 | 10 | main_page_id!: string; 11 | 12 | user_id!: string | null; 13 | 14 | encrypted_rehashed_password_hash!: Uint8Array | null; 15 | 16 | access_keyring!: Uint8Array | null; 17 | encrypted_content_keyring!: Uint8Array; 18 | 19 | public_keyring!: Uint8Array; 20 | encrypted_private_keyring!: Uint8Array; 21 | 22 | permanent_deletion_date!: Date | null; 23 | 24 | are_join_requests_allowed!: boolean; 25 | } 26 | -------------------------------------------------------------------------------- /packages/@stdlib/vue/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@deeplib/tsconfig/base.json", 3 | 4 | "compilerOptions": { 5 | "types": ["vitest/globals"], 6 | 7 | "baseUrl": ".", 8 | 9 | "rootDir": "src", 10 | "outDir": "dist", 11 | 12 | "paths": { 13 | "src/*": ["src/*"], 14 | 15 | "@stdlib/*": ["../../../packages/@stdlib/*/src"] 16 | } 17 | }, 18 | 19 | "references": [{ "path": "../../../packages/@stdlib/misc/tsconfig.json" }], 20 | 21 | "include": ["*.ts", "src/**/*.ts"], 22 | 23 | "tsc-alias": { 24 | "replacers": { 25 | "base-url": { 26 | "enabled": false 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /apps/realtime-server/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:16 AS builder 2 | 3 | RUN npm install -g pnpm@^8.0.0 4 | 5 | WORKDIR /build 6 | COPY ./ ./ 7 | RUN pnpm install --filter deepnotes --filter @deepnotes/realtime-server... 8 | RUN pnpm --filter @deepnotes/realtime-server run bundle 9 | 10 | FROM node:16-alpine AS runner 11 | 12 | RUN npm install -g pnpm@^8.0.0 13 | RUN mkdir /usr/local/pnpm 14 | ENV PNPM_HOME="/usr/local/pnpm" 15 | ENV PATH="${PATH}:/usr/local/pnpm" 16 | RUN pnpm add -g pm2 17 | 18 | WORKDIR /app 19 | COPY --from=builder /build/apps/realtime-server/dist/ ./ 20 | RUN pnpm init 21 | RUN pnpm install knex ws pg 22 | CMD pm2 start /app/index.js -i max && pm2 logs -------------------------------------------------------------------------------- /apps/client/src/code/pages/composables/use-window-resize-listener.ts: -------------------------------------------------------------------------------- 1 | export function useWindowResizeListener() { 2 | onMounted(() => { 3 | onResize(); 4 | 5 | window.addEventListener('resize', onResize); 6 | }); 7 | 8 | function onResize() { 9 | if ( 10 | window.innerWidth < 1080 && 11 | uiStore().leftSidebarExpanded && 12 | uiStore().rightSidebarExpanded 13 | ) { 14 | mainLogger.sub('useWindowResizeListener').info('Collapse right sidebar'); 15 | 16 | uiStore().rightSidebarExpanded = false; 17 | } 18 | } 19 | 20 | onBeforeUnmount(() => { 21 | window.removeEventListener('resize', onResize); 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/account/two-factor-auth/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { disableProcedure } from './disable'; 4 | import { enableRouter } from './enable'; 5 | import { forgetTrustedDevicesProcedure } from './forget-devices'; 6 | import { generateRecoveryCodesProcedure } from './generate-recovery-codes'; 7 | import { loadProcedure } from './load'; 8 | 9 | export const twoFactorAuthRouter = trpc.router({ 10 | enable: enableRouter, 11 | load: loadProcedure(), 12 | generateRecoveryCodes: generateRecoveryCodesProcedure(), 13 | forgetTrustedDevices: forgetTrustedDevicesProcedure(), 14 | disable: disableProcedure(), 15 | }); 16 | -------------------------------------------------------------------------------- /packages/@deeplib/db/src/models/group-join-invitation.ts: -------------------------------------------------------------------------------- 1 | import type { GroupRoleID } from '@deeplib/misc'; 2 | import { Model } from 'objection'; 3 | 4 | export class GroupJoinInvitationModel extends Model { 5 | static override tableName = 'group_join_invitations'; 6 | 7 | static override idColumn = ['group_id', 'user_id']; 8 | 9 | group_id!: string; 10 | user_id!: string; 11 | 12 | inviter_id!: string; 13 | 14 | role!: GroupRoleID; 15 | 16 | encrypted_access_keyring!: Uint8Array | null; 17 | encrypted_internal_keyring!: Uint8Array; 18 | 19 | encrypted_name!: Uint8Array; 20 | encrypted_name_for_user!: Uint8Array; 21 | 22 | creation_date!: Date; 23 | } 24 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/pages/clear-recent-pages.ts: -------------------------------------------------------------------------------- 1 | import { once } from 'lodash'; 2 | import type { InferProcedureOpts } from 'src/trpc/helpers'; 3 | import { authProcedure } from 'src/trpc/helpers'; 4 | 5 | const baseProcedure = authProcedure; 6 | 7 | export const clearRecentPagesProcedure = once(() => 8 | baseProcedure.mutation(clearRecentPages), 9 | ); 10 | 11 | export async function clearRecentPages({ 12 | ctx, 13 | }: InferProcedureOpts) { 14 | return await ctx.usingLocks([[`user-lock:${ctx.userId}`]], async () => { 15 | await ctx.dataAbstraction.patch('user', ctx.userId, { 16 | recent_page_ids: [], 17 | }); 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /apps/client/src/stores/pages.ts: -------------------------------------------------------------------------------- 1 | import type { DeepNotesNotification } from '@deeplib/misc'; 2 | import { defineStore } from 'pinia'; 3 | 4 | export const GROUP_CONTENT_KEYRING = 'group-content-keyring'; 5 | 6 | export const usePagesStore = defineStore('pages', () => { 7 | const state = reactive({ 8 | loading: true, 9 | 10 | dict: {} as Record, 11 | 12 | notifications: { 13 | items: [] as DeepNotesNotification[], 14 | hasMore: true, 15 | lastNotificationRead: -1 as number | undefined, 16 | }, 17 | 18 | groups: {} as Record }>, 19 | }); 20 | 21 | return { 22 | ...toRefs(state), 23 | }; 24 | }); 25 | -------------------------------------------------------------------------------- /packages/@deeplib/data/src/data-hashes/customer/index.ts: -------------------------------------------------------------------------------- 1 | import { validateDataHash } from '@stdlib/data/src/universal'; 2 | import { once } from 'lodash'; 3 | 4 | import { userId } from './user-id'; 5 | 6 | const UserModel = once( 7 | async () => 8 | (process.env.CLIENT ? null : (await import('@deeplib/db')).UserModel)!, 9 | ); 10 | 11 | export const customer = validateDataHash({ 12 | model: UserModel, 13 | 14 | get: async ({ suffix: customerId, columns, trx }) => 15 | await (await UserModel()) 16 | .query(trx) 17 | .where('customer_id', customerId) 18 | .select(columns) 19 | .first(), 20 | 21 | fields: { 22 | 'user-id': userId, 23 | }, 24 | }); 25 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/pages/clear-favorite-pages.ts: -------------------------------------------------------------------------------- 1 | import { once } from 'lodash'; 2 | import type { InferProcedureOpts } from 'src/trpc/helpers'; 3 | import { authProcedure } from 'src/trpc/helpers'; 4 | 5 | const baseProcedure = authProcedure; 6 | 7 | export const clearFavoritePagesProcedure = once(() => 8 | baseProcedure.mutation(clearFavoritePages), 9 | ); 10 | 11 | export async function clearFavoritePages({ 12 | ctx, 13 | }: InferProcedureOpts) { 14 | return await ctx.usingLocks([[`user-lock:${ctx.userId}`]], async () => { 15 | await ctx.dataAbstraction.patch('user', ctx.userId, { 16 | favorite_page_ids: [], 17 | }); 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /packages/@stdlib/data/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@deeplib/tsconfig/base.json", 3 | 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | 7 | "rootDir": "src", 8 | "outDir": "dist", 9 | 10 | "paths": { 11 | "src/*": ["src/*"], 12 | 13 | "@stdlib/*": ["../../../packages/@stdlib/*/src"] 14 | } 15 | }, 16 | 17 | "references": [ 18 | { "path": "../../../packages/@stdlib/base64/tsconfig.json" }, 19 | { "path": "../../../packages/@stdlib/misc/tsconfig.json" } 20 | ], 21 | 22 | "include": ["src/**/*.ts"], 23 | 24 | "tsc-alias": { 25 | "replacers": { 26 | "base-url": { 27 | "enabled": false 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/pages/set-encrypted-default-note.ts: -------------------------------------------------------------------------------- 1 | import { once } from 'lodash'; 2 | import type { InferProcedureOpts } from 'src/trpc/helpers'; 3 | import { authProcedure } from 'src/trpc/helpers'; 4 | import { z } from 'zod'; 5 | 6 | const baseProcedure = authProcedure.input(z.instanceof(Uint8Array)); 7 | 8 | export const setEncryptedDefaultNoteProcedure = once(() => 9 | baseProcedure.mutation(setEncryptedDefaultNote), 10 | ); 11 | 12 | export async function setEncryptedDefaultNote({ 13 | ctx, 14 | input, 15 | }: InferProcedureOpts) { 16 | await ctx.dataAbstraction.patch('user', ctx.userId, { 17 | encrypted_default_note: input, 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /apps/client/src/layouts/PagesLayout/MainContent/DisplayPage/DisplayScreens/DisplayWorld/DisplayNote/NoteSection/NoteContainerSection/NoteContainerSection.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 17 | -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/users/pages/set-encrypted-default-arrow.ts: -------------------------------------------------------------------------------- 1 | import { once } from 'lodash'; 2 | import type { InferProcedureOpts } from 'src/trpc/helpers'; 3 | import { authProcedure } from 'src/trpc/helpers'; 4 | import { z } from 'zod'; 5 | 6 | const baseProcedure = authProcedure.input(z.instanceof(Uint8Array)); 7 | 8 | export const setEncryptedDefaultArrowProcedure = once(() => 9 | baseProcedure.mutation(setEncryptedDefaultArrow), 10 | ); 11 | 12 | export async function setEncryptedDefaultArrow({ 13 | ctx, 14 | input, 15 | }: InferProcedureOpts) { 16 | await ctx.dataAbstraction.patch('user', ctx.userId, { 17 | encrypted_default_arrow: input, 18 | }); 19 | } 20 | -------------------------------------------------------------------------------- /apps/client/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .thumbs.db 3 | node_modules 4 | 5 | # Quasar core related directories 6 | .quasar 7 | /dist 8 | 9 | # Cordova related directories and files 10 | /src-cordova/node_modules 11 | /src-cordova/platforms 12 | /src-cordova/plugins 13 | /src-cordova/www 14 | 15 | # Capacitor related directories and files 16 | /src-capacitor/www 17 | /src-capacitor/node_modules 18 | 19 | # BEX related directories and files 20 | /src-bex/www 21 | /src-bex/js/core 22 | 23 | # Log files 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # Editor directories and files 29 | .idea 30 | *.suo 31 | *.ntvs* 32 | *.njsproj 33 | *.sln 34 | 35 | /auto-imports.d.ts 36 | /components.d.ts -------------------------------------------------------------------------------- /apps/app-server/src/trpc/api/groups/index.ts: -------------------------------------------------------------------------------- 1 | import { trpc } from 'src/trpc/server'; 2 | 3 | import { deletionRouter } from './deletion'; 4 | import { getMainPageIdProcedure } from './get-main-page-id'; 5 | import { getPagesProcedure } from './get-pages'; 6 | import { getUserIdsProcedure } from './get-user-ids'; 7 | import { passwordRouter } from './password'; 8 | import { privacyRouter } from './privacy'; 9 | 10 | export const groupsRouter = trpc.router({ 11 | getMainPageId: getMainPageIdProcedure(), 12 | 13 | getUserIds: getUserIdsProcedure(), 14 | 15 | getPages: getPagesProcedure(), 16 | 17 | password: passwordRouter, 18 | privacy: privacyRouter, 19 | 20 | deletion: deletionRouter, 21 | }); 22 | -------------------------------------------------------------------------------- /apps/client/src/layouts/PagesLayout/MainToolbar/Notifications/NotificationsBadge.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 27 | --------------------------------------------------------------------------------