Coder Social home page Coder Social logo

un / inbox Goto Github PK

View Code? Open in Web Editor NEW
1.2K 15.0 83.0 7.24 MB

Modern email for teams and professionals. A replacement for outdated email technology and tools. Alt to hey.com, front.com, missiveapp.com

Home Page: https://uninbox.com

License: Other

JavaScript 0.20% TypeScript 70.34% Vue 29.08% CSS 0.25% HTML 0.13%
chat communication conversations email platform smtp-client coss infrastructure nuxt nuxt3

inbox's Introduction

Join The UnInbox Discord Community Github Stars

Commits-per-month

UnInbox Logo

UnInbox

The Open Source Communication Infrastructure

To our Website & App Β»

UnInbox Twitter Β· UnInbox Discord Server


🚧 Current Status

UnInbox is Live! We are working on more features and infrastructure to make UnInbox better. Please join our Discord community to get the latest updates and to provide feedback. Join at app.uninbox.com.


About

Our core infrastructure is designed from the ground up for effective communication between you and the rest of the world.

The webapp provides a flavoured experience of what email communication would be if it was re-imagined for how we communicate today.

Features like "team collaboration", "conversation notes" and "new sender screener" are native, making communication easier and more intuitive.

Built to work with your current email infrastructure or replace it entirely.

We're not here to kill email, we're bringing it up to date, killing inboxes along the way.

UnInbox isn't another email service, its a better way to do email.

And email is just the start


Why

The first email was sent almost 45 years ago (1979). Before the invention of the mobile telephone.

Communication workflows have changed dramatically since then, but the email experience has remained the same.

The volume of emails we receive has exploded in recent years, with more noise than actual conversations.

Email is not built for today's noisy, remote, highly collaborative world.

But email is universal, so we can't force the world to replace it.

Instead, we're detaching from its legacy underpinnings, to build something modern on top.


Tech Stack

UnInbox is built with the following epic technologies & tools:

p.s. Things will change over time!

Running Locally

To get a local copy up and running, follow these simple steps.

Prerequisites

Here is what you need to be able to run UnInbox locally.

Setup

  1. Clone the repo into a public GitHub repository (or fork https://github.com/un/inbox/fork). If you plan to distribute the code, keep the source code public to comply with AGPLv3. To clone in a private repository, contact us to acquire a commercial license

    git clone https://github.com/un/inbox.git

    If you are on Windows, run the following command on gitbash with admin privileges:
    > git clone -c core.symlinks=true https://github.com/un/inbox.git
    See docs for more details.

  2. Go to the project folder

    cd UnInbox
  3. Check and install the correct node/pnpm versions

    nvm install
  4. Install packages with pnpm

    pnpm i
  5. Set up your .env.local file

    • Duplicate .env.local.example to .env.local. This file is already pre-configured for use with the local docker containers

      mac

       cp .env.local.example .env.local

      windows

       copy .env.local.example .env.local
  6. Start the docker containers

    pnpm run docker:up
  7. Sync the schema with the database:

    pnpm run db:push
  8. In another terminal window, start the app and all services

    pnpm run dev

Self Hosting

Self hosting will be possible, but requires some additional manual configuration for email. Please check out Discord community for information on how to self-host UnInbox in production

inbox's People

Contributors

aashish-upadhyay-101 avatar adityadeshlahre avatar affenity avatar akshatarora130 avatar ankur1493 avatar babblebey avatar blankparticle avatar chronark avatar cstrnt avatar daallgeier avatar danielroe avatar dependabot[bot] avatar errolfernandes avatar ezra-en avatar fahadshahbaz avatar flo4604 avatar ginogits avatar iammohan01 avatar kmkoushik avatar maciej-ka avatar mahansky avatar mcpizza0 avatar mooyg avatar peerrich avatar returnkirbo avatar sean-brydon avatar simonorzel26 avatar skushagra9 avatar waitwhatjusthappened avatar xmohamd avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

inbox's Issues

avatar upload component = fugly

the current avatar upload components are fugly
image

across the app we use round avatars, the current implementation is from legacy code/design

we need a new avatar/upload component that shows existing/blank avatar and a button to upload the avatar
please submit examples/designs before working on this issue

places to change:
/apps/web-app/pages/[orgSlug]/settings/org/index.vue
/apps/web-app/pages/[orgSlug]/settings/user/profiles.vue
/apps/web-app/pages/join/profile.vue

bug(web-app): handle if user does not have org

if a user dosnt have a default org (or any org) they will be redirected and get tons of errors

best place to handle this would be in the org redirect: apps/web-app/pages/redirect.vue

we have a "new org" form that would be a good candidate as a destination: /apps/web-app/pages/[orgSlug]/settings/org/new.vue
but we cant redirect here as its under the [orgSlug] folder and would send back to redirect
the new page would need to factor in the auth middleware to ensure users can navigate to it

bug(web): scrollbars visible

scrollbars are visible and ugly in many parts of the app
we're using tailwind and need to resolve this

some examples:
image
image

feat(web): create email templates for transactional email

we use vue-email for email templating and need some transactional email templates created

these are the needed emails and their props:

verify recovery email
props: {
username: string;
verification code: string;
verification link: string;
}

login code
props: {
username: string;
login code: string;
}

invite
props: {
inviterName: string;
inviterAvatarId: string
orgName: string;
orgAvatarId: string;
inviteCode: string;
expiryDate: datetime;
}

templates should be created in apps/web-app/emails
the folder contains a vercel email that can be used as a template

be sure to check https://vuemail.net/ docs

handle passkey creation error

I've tried creating an account in firefox where I don't have any passkey setup.
Therefore the setup failed and an error was logged to the console but the UI still displayed a loading state.

Optimally there should be a toast giving some feedback to the user

chore(repo): set package.json node/pnpm engine version

We use Node v20 for our development

to ensure contributors can run the code on their system without odd node conflicts
we should add the following to all package.json files across the repo

"engines": {
  "node": ">=20",
  "pnpm": ">=8"
}

Draft: Save user device (name/type) in session data

When generating user session - we should pass in the user's device (type/name) and browser.

This will be stored in the session data, and used to give users an easy way to manage their sessions from the UI

examples:
google
image

notes:

  • using user-agent is not reliable since all chromium browser report as chrome
  • Arc browser can be detected client side using getComputedStyle(document.documentElement).getPropertyValue('--arc-palette-title') ? 'Is Arc' : 'Is Not Arc'
  • Brave browser can be detected client side using !navigator.brave or typeof navigator?.brave?.isBrave === 'function'
  • We need a way to detect if the user is using the PWA, this may be possible through a custom user-agent

Minor grammatical mistakes on landing FAQs

Q: Can I use UnInbox for my personal email?
A: Yes, most of our features are designed for collaboration, but everything should work if its just you.
Suggestion: Yes, most of our features are designed for collaboration, but everything should work even if it's just you.


Q: Why are custom domains not available on the free plan?
A: There is a high risk of spam and abuse with custom domains, and this could damage the all our sending infrastructure. We require a paid plan as verification and to cover the additional technical requirements of ensuring safe email sending across our platform.
Suggestion: There is a high risk of spam and abuse with custom domains, and this could damage our infrastructure. We require a paid plan as verification and to cover the additional technical requirements of ensuring safe email sending across our platform.


Q: Will you have a calendar?
A: It's planned, but will come after the email app is stable.
Suggestion: Our initial focus is ensuring the stability of the email app and a seamless experience for its users. We'll introduce new features, including the calendar, once the app is stable.


Q: Can I migrate my emails from Google or another provider?
Q: We want to make De-Googling and migrating from other providers super easy. Its not yet possible but its on our priorities list.
Suggestion: We aim to make De-Googling and migrating from other email service providers super easy. While it's not possible yet, it's on our list of priorities.


Q: Will your prices ever increase?
A: Yes, as time goes on things become more expensive. BUT, when you have an active subscription, the price is locked in till your subscription expires.
Suggestion: Yes, over time, prices may increase due to rising costs. However, if you have an active subscription, your price will be locked in until your subscription expires.


Q: Can I use UnInbox with another email client?
A: No, we are built on very different technologies and theres simply no way to make them compatible. If you really need to use another email client, check for another service or use our forwarding feature.
Suggestion: No, we are built on very different technologies and there's simply no way to make them compatible. If you really need to use another email client, check for another service or use our forwarding feature.


Q: Can I forward mail in from another service?
A: Yes, you get a personal email address with UnInbox, and a dedicated forwarding address. Any emails sent to your forwarding address will appear in your UnInbox. You can also forward all emails for a custom domain to your UnInbox organization.
Suggestion: Can I forward emails from another email service provider?


Q: Will you do what Skiff did and abandon us?
A: No, we do not plan on getting acquired, that's not our end goal. If we were ever to shut down, our code will remain freely available for you to self-host and we will take some steps to ensure the online platform can remain active.
Suggestion: No, we do not plan on getting acquired, that's not our end goal. If we were ever to shut down, our code will remain freely available for you to self-host and we will take some steps to ensure that the online platform will remain active.

When adding a group, should be able to add email identity for the group in the same modal

Currently:
When adding a new group, you can enter the name, description and color via the add new group modal
new modal file path: ./apps/web-app/components/settings/addNewGroup.vue
image

We need to add a toggle to also create an email identity for the group, based on the add new email modal

All the logic and inputs already exist, see add new email modal for code: ./apps/web-app/components/settings/addNewEmail.vue
the new toggleable input options should be: address, domain and send name. reuse the same input validation that currently exists. the group should be set as the "deliver messages to".

we should re-use the same trpc endpoint that creates email identities to avoid duplicating backend logic/code: $trpc.org.mail.emailIdentities.createNewEmailIdentity

--

If you want to work on this, please tag me

Update Avatar storage and image url generation

we need to update the way we store and use avatars to ensure caching of local images are updated, and to reduce console errors when an avatar is not set.

changes needed:

  • add a avatarId field to the following tables: userProfiles, orgs, userGroups, contacts
  • update storage app avatar.post api endpoint to generate avatarId using nanoIdLong, use for s3 upload (with new object key of (${typeObject.value}_${avatarId}/${size.name}), save to db table and return avatarId to webapp
  • update all dbqueries returning userProfiles, orgs, userGroups, contacts to also return the avatarId column
  • update UnUiAvatar component to accept new avatarId prop for use in useUtils().generateAvatarUrl()
  • update generateAvatarUrl to use new avatarId
  • update all UnUiAvatar component instances to pass in new avatarId prop

awaiting final confirmation

previous issue

when a user, org, group or contact does not have an avatar image, an error is logged out to the console from the Avatar component ![image](https://github.com/uninbox/UnInbox/assets/17185737/141d654f-4c08-4a72-b4e4-5ce5f32debb4) https://github.com/nuxt/ui/blob/dev/src/runtime/components/elements/Avatar.vue

we do not know if an object has an avatar image or not
so we always pass a URL to the avatar component, which tries to fetch the avatar

we need a way to suppress these error logs, or hide them in another way

if we cant remove them, we may need to add a hasAvatar boolean to the profile tables for each object type

@cstrnt thoughts

fix(web): when refreshing domain DNS, should also refresh dns in postal server

postal server only refreshes the DNS once every 24 hours
when adding a new domain in web, users can refresh the DNS
if the dns is valid, we enable sending

currently, we dont ask postal to refresh the dns
if the user starts sending before postal has been refreshed it will lead to all outgoing emails to be labled as "via ...."
image

to fix this, we need to add a new postal puppet to refresh the domain's dns, and trigger it to run each time the web dns is checked

feat(web-app): User Security Page

Once #79 merges, we need to add a new security settings page so users can manage their own security

they should be able to:

  • verify their recovery email address (if not verified)
  • change their recovery email address
  • change their password (if one is set, or set one up if not)
  • switch on/off password auth if they have passkeys enabled
  • setup TOTP 2FA (separate issue)
  • manage their passkeys (add, remove)
  • manage their user sessions (destroy session, log out of all devices)

security(web-app): Add CSRF protection

We have some mitigations in place, but we are not entirely protected from CSRF attacks

There is a handy nuxt-module for CSRF protection, but it generally relies on using the custom fetch composable for full operations: https://github.com/morgbn/nuxt-csurf
the module also has limitations and provides little abstraction

Luckily, we use tRPC, and all app API stuff happens over tRPC (except for logout)
so we can add the CSRF token to the header in the tRPC client and create a tRPC middleware to validate the token

The generation of the initial CSRF token would need to be done, stored somewhere serverside, and have a way to link it to a user session.

As per the CSRF mitigation guide: https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern

Current thoughts to implement:
When user hits login page, generate "unattached" CSRF token, store in cache, return to user
When user logs in, generate new CSRF, add to userSession data stored in cache, return to user
tRPC client should inject the CSRF token into the headers

  • a question: should we store the client side CSRF token in a cookie, or in some other JS accessible data store

Open to input and ideas

Some settings pages with back arrow dont work

some settings pages have a < back arrow to go back to main page
this link does not work correctly on some

these are usually on the details page of one entry (single domain, single group etc)

dx annoyance: switch off drizzleorm logger

currently drizzle logs out all the sql queries it send to the db
this fills up the runtime logs with meaningless junk and can sometimes hide crucial errors
image

we should switch off drizzle's logging and enable it manually when debugging db issues

when uploading avatar, storage server has error and new avatar not rendered on page

when uploading a new avatar, the upload does succeed and the image is accessible
but the avatar on the page does not refresh to new value

prev error (fixed) the storage server logs out an error ``` @uninbox/storage:dev: [nitro] [uncaughtException] TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Object @uninbox/storage:dev: at write_ (node:_http_outgoing:879:11) @uninbox/storage:dev: at ServerResponse.end (node:_http_outgoing:1030:5) @uninbox/storage:dev: at Immediate. (file:///Users/omar/code/UnInbox/node_modules/.pnpm/[email protected]/node_modules/h3/dist/index.mjs:682:24) @uninbox/storage:dev: at process.processImmediate (node:internal/timers:478:21) { @uninbox/storage:dev: code: 'ERR_INVALID_ARG_TYPE' @uninbox/storage:dev: } ```
Error is fixed by https://github.com//pull/48

bug(web): page navigation blocked due to profile in nav bar menu

issue appeared where page navigation was being blocked (url updates but new page content does not render
no clear errors in the logs

after some diagnosis I discover that 1 single trpc call was the cause
the trpc call exists on the main layout navigation, thus blocking almost all navigation
if the to page includes a layout change, navigation works correctly
if the to page does not include a layout change, the URL will update, network calls on the to page will execute, but nothing new will render

to unblock the app, I removed the call here: 4f771db

we need to identify the cause and fix the issue so we can re-implement the profile
image

Bug : Zod input schema validation fix required on input fields.

Hey contributor πŸ‘‹
currently: In few place input validation is broken. [Empty Spaces OR White Spaces can be entered/updated]

  1. Profile Page
    image

  2. Invite Page
    image

  3. Add Group Component
    image

  4. Add New Email Address Page
    image

[please check in other places too]

Update Request : Show throw Errors in below the input fields OR Should show TOAST messages .

like this one below [ only on page based field (not on the components) ]
&
[on components just need to show error below input fields ]
image

feat(mailtools): improve removal of email trackers

when updating avatar images, local cached avatar image is still rendered

when a user updates their profile or org profile avatar, the browser still uses the locally cached image
this is because avatar URLs are fixed and do not change with updates

we have a workaround in place to append a timestamp to the avatar URLs, but this means that the app has to re-fetch the avatar from the server every single time, incurring latency and cost ($) for transport
https://github.com/uninbox/UnInbox/blob/904fb08d27f45b2555cead718ea06b36cc7784b9/apps/web-app/composables/utils.ts#L32

we need a better permanent fix for this issue

possible solution:

  • add updatedAt column to userProfile, orgs, userGroups & contacts tables. append the updatedAt value to generateAvatarUrl function

thoughts @cstrnt ?

(web) handle trpc errors: switch to tRPC useMutation

Across the repo we currently use tRPC mutate composable provided by nuxt-trpc, where the returned value === data

const newDomainResponse = await $trpc.org.mail.domains.createNewDomain.mutate({
  domainName: newDomainNameValue.value
});

there are many instances where tRPC will throw an error (we use tRPC to handle all backend errors)
the tRPC client handles these by showing a toast message with the error

we dont have any way to reset loading state for buttons on the page, requiring a full refresh to submit again

nuxt-trpc recently added a useMutation composable : wobsoriano/trpc-nuxt#132

the above example would become

const createNewDomainTrpc =
  $trpc.org.mail.domains.createNewDomain.useMutation();
await createNewDomainTrpc.mutate({
  domainName: newDomainNameValue.value
});

the createNewDomainTrpc object now contains a status key with possible values 'idle' | 'pending' | 'success' | 'error'

we can check if tRPC threw an error and reset the form loading state

if (createNewDomainTrpc.status.value === 'error') {
  buttonLoading.value = false;
 // show any additional errors/toast messages
} else {
  // continue
}

we should switch to using `useMutation` as per above examples across the app and implement form status/button resets where needed
this will ensure consistent dx and give access to the additional keys for future use

Desktop Application

There appears to be demand for a desktop app.
https://discord.com/channels/1113119653246545961/1207658838925385770

I propose we use Tauri to begin with. It's lighter than Electron, allows us to reuse our existing web-app frontend, and can support localhost if needed for self-hosting via their 1st-party localhost plugin for production use.

Tauri will allow us to iterate on top of our existing web app while providing more stable data access interfaces (via their rust bindings to sql) and because it's cross-platform, allows us to bring an enhanced desktop experience very quickly to all desktop users.

There is an option for mobile builds, but that is still in beta. imo, it would be better for us to design a separate mobile application optimised for that platform, rather than deriving off of the web-app's mobile layout.

Alternative Login Method: One Time Code

Problem
Currently, the only way to use UnInbox is by Passkey Auth. While passkeys are a super nice technology and are really secure they're not that well known (yet) and this might hinder people from using UnInbox and that should never be a blocker.

Constraints:

  • no external services
  • great user experience

Proposed Solution
Implement a One Time Code login method. When the user wants to sign-up / login they will need to enter an email address.
They will receive an email containing a code containing 6 characters (number/uppercase letters). They can then enter this code in combination with their email to login or signup.

Technical Details

  • The code must be shortlived (< 3 mins?) and bound to an email address (compound index) and should be stored hashed in the database.
  • We need to write a custom auth.js provider for that, the email/magiclink provider should be a good reference / starting point

domainDetails page: update data to use Accordion

Page: https://github.com/uninbox/UnInbox/blob/main/apps/web-app/pages/%5BorgSlug%5D/settings/org/mail/domains/%5BdomainId%5D.vue

to view the page in action, you need to add a domain.

This page uses a custom accordion that was created before we switched to NuxtUI library

NuxtUI has a nice accordion component: https://ui.nuxt.com/elements/accordion#multiple
we will need to replace the current badges with the already existing UnUiBadge component

The Accordion should render the same data that exists now

reach out on discord if you have any questions

mail parser dosnt remove proton mail signatures and quotes

with the adopted Tempo mail parser, it dosnt remove the signatures and quotes from several providers
we should add additional attributes for it to remove

also, there are often lots of additional styles leftover from the various email clients, we should look to remove these too!

security(web): add lastLoginAt

we should save the last time a user has logged in to the database
this could be done when we create a session for the user

the data would be used to check for active/inactive users by combining lastLoginAt with a check on active sessions

Update repo docs to add instructions for windows WSL mode

Local dev dosnt work directly on a windows machine
Windows users should instead set up and use WSL
@McPizza0 created a lengthy guide to set thing up as a video: https://www.youtube.com/watch?v=xL-nwGpQ0Ng
we need to summarize this into steps and potentially add it to a linked doc from the main readme


Original issue:

I ran into this while tryna set-up my local dev server on my windows machine.

Windows users encounter errors running scripts due to differences in command syntax. I think the scripts across all apps have been written in a ways that isn't exactly cross-compactible, the current script look like they run only on Unix-based systems (I think 😬).

Steps to Reproduce:

  1. Clone the repository on a Windows machine.
  2. Run pnpm run dev

Expected Behavior:

Scripts should run without errors on Windows.

Actual Behavior:

Windows throws an error because it does not recognize the syntax PORT. Notice the specific error in the log below...

> [email protected] dev C:\Users\User\Documents\Projects\open-source\uninbox
> dotenv -e .env.local -- turbo run dev --filter=!@uninbox/landing


// [minimised]
@uninbox/web-app:dev:
@uninbox/web-app:dev: > @uninbox/web-app@ dev C:\Users\User\Documents\Projects\open-source\uninbox\apps\web-app
@uninbox/web-app:dev: > PORT=3000 nuxt dev --host
@uninbox/web-app:dev:
@uninbox/web-app:dev: 'PORT' is not recognized as an internal or external command,  // <---- πŸ‘ˆ πŸ‘ˆ πŸ‘ˆ πŸ‘ˆ πŸ‘ˆ πŸ‘ˆ 
@uninbox/web-app:dev: operable program or batch file.
@uninbox/web-app:dev:  ELIFECYCLE  Command failed with exit code 1.
@uninbox/postal-puppet:build:puppet:
@uninbox/postal-puppet:build:puppet: > @uninbox/[email protected] build:puppet C:\Users\User\Documents\Projects\open-source\uninbox\packages\postal-puppet
@uninbox/postal-puppet:build:puppet: > unbuild
@uninbox/postal-puppet:build:puppet:
@uninbox/storage:dev:
@uninbox/storage:dev: > @uninbox/storage@ dev C:\Users\User\Documents\Projects\open-source\uninbox\apps\storage
@uninbox/storage:dev: > PORT=3200 npx nitropack dev
@uninbox/storage:dev:
@uninbox/storage:dev: 'PORT' is not recognized as an internal or external command,  // <---- πŸ‘ˆ πŸ‘ˆ πŸ‘ˆ πŸ‘ˆ πŸ‘ˆ πŸ‘ˆ 
@uninbox/storage:dev: operable program or batch file.
@uninbox/storage:dev:  ELIFECYCLE  Command failed with exit code 1.
// [minimised]

Workaround:

Modify the dev scripts in all apps package.json using the format below in places where PORT are set

"dev": "set PORT=3*** && <command>"

Replace 3*** with appropriately stated port and replace <command> with the already existing command

Proposed Solution:

Update all scripts in the repository to use cross-platform compatible syntax.

Additional Notes:

  • This issue affects Windows users and should be resolved for better cross-platform compatibility.

Normalize User / Project Id Types

Currently we have some ids stored as numbers, some as strings (see here for more details: #49 (comment))

Those should be normalized so we don't have to do conversions anymore when comparing them.

Also the current conversions should be removed

Move tiptap extensions to separate tiptap package

Our backend and front end are split across two apps
each of them needs to know which tiptap extensions are installed/used
currently this is set manually in each app, but could become de-synced if changed in only one

we should create a new package to handle tiptap types and export the extensions from there
we should also create different sets of extensions for future use (tiptapConversations for email stuff, tiptapDocuments for docs etc..)

@BlankParticle has offered to do this

error when adding sub domain

when adding a new domain, we use the createNewDomain procedure in apps/web-app/server/trpc/routers/orgRouter/mail/domainsRouter.ts

this validates the domain actually exists by trying to resolve the name servers for the input domain name.
it is assumed that every single registered domain has nameservers set.

      await dns.promises.resolveNs(domainName).catch(() => {
        throw new TRPCError({
          code: 'FORBIDDEN',
          message: 'Domain does not exist or is not registered'
        });
      });

subdomains do not have their own nameservers and this the error is thrown

fix:

ideally, if the input domain contains more than one . we would split it at the first occurring . and keep going till theres only 1 . left. if still no results, then throw the error

potential issues:
this could throw some false positives when the input is domain.co.uk (a valid domain) since its also possible to register domain.uk and co.uk has some name servers

mitigation:
domains will not be available for sending till dns is verified anyway. and 3 days after adding and not being verified, domains are disabled

thanks @daallgeier for highlighting this issue

Update landing site "OSS-Friends" page

File location: apps/landing-page/pages/oss-friends.vue

This page is part of a Open Source projects network
The current page was made quite a while ago and never updated

The design of the page should be updated to use components from NuxtUi: https://ui.nuxt.com/getting-started
Heres some inspirations; https://documenso.com/oss-friends https://www.hanko.io/oss-friends https://infisical.com/infisical-friends

To get the data, we need to query the api located at https://formbricks.com/api/oss-friends

The link to the oss-page should be added to the Footer component

Finally, we should set the route rule to cache the page with a ttl of 24 hours (swr mode): https://nuxt.com/docs/guide/concepts/rendering#route-rules

when a user creates or joins a new org, create new profile

I thought this was already implemented, but a user has a profile per organization
when creating a new org, or joining a new one as an existing user, we should duplicate their current profile and create a new one for the user

currently the users existing profile is used

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.