Compare commits

..

8 Commits

Author SHA1 Message Date
Henry
808d23bd15 fix: add google to the remote patterns 2025-06-05 12:58:01 +01:00
Lonneke Vuur
1b2389d618 fix: issue 23, handle external URLs in avatar rendering 2025-06-05 10:28:26 +02:00
LovelessCodes
c9a9779e79 feat: include column name in board repository query response to use in board PageHead (#20) 2025-06-05 06:08:20 +01:00
LovelessCodes
356e35964b feat: allow public card access without authentication (#19) 2025-06-05 06:05:03 +01:00
Henry
1698b744e4 chore: fix labels on issue templates 2025-06-05 05:41:21 +01:00
Henry
27c0c0a5e8 chore: update issue templates 2025-06-05 05:37:31 +01:00
Henry
2129a60d22 chore: setup github issue templates 2025-06-05 05:22:22 +01:00
Henry
84dd9a9b6d feat: support SMTP via nodemailer (#17) 2025-06-04 12:33:24 +01:00
9 changed files with 99 additions and 14 deletions

37
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,37 @@
---
name: "\U0001F41B Bug Report"
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
## 🐛 Bug Report
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '...'
3. Scroll down to '...'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Environment (please complete the following information):**
- OS: [e.g. macOS, Windows, Linux]
- Browser [e.g. chrome, safari]
- Node version [e.g. 20]
- App version/commit [if applicable]
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,30 @@
---
name: "✨ Feature Request"
about: Suggest an idea for this project
title: ''
labels: feature
assignees: ''
---
## ✨ Feature Request
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
**Implementation ideas (optional)**
If you have any ideas about how this feature could be implemented, please share them here.
**Would you like to work on this feature?**
- [ ] Yes, I'd like to help implement this feature
- [ ] No, I'm just suggesting the feature

View File

@@ -93,7 +93,7 @@ pnpm dev
| `S3_ACCESS_KEY_ID` | S3 access key | For file uploads | `xxx` |
| `S3_SECRET_ACCESS_KEY` | S3 secret key | For file uploads | `xxx` |
| `NEXT_PUBLIC_STORAGE_URL` | Storage service URL | For file uploads | `https://storage.kanbn.com` |
| `NEXT_PUBLIC_STORAGE_DOMAIN` | Storage domain name | For file uploads | `storage.kanbn.com` |
| `NEXT_PUBLIC_STORAGE_DOMAIN` | Storage domain name | For file uploads | `kanbn.com` |
| `NEXT_PUBLIC_AVATAR_BUCKET_NAME` | S3 bucket name for avatars | For file uploads | `avatars` |
See `.env.example` for a complete list of supported environment variables.

View File

@@ -26,7 +26,16 @@ const config = {
typescript: { ignoreBuildErrors: true },
images: {
domains: [env("NEXT_PUBLIC_STORAGE_DOMAIN") ?? ""],
remotePatterns: [
{
protocol: "https",
hostname: `*.${env("NEXT_PUBLIC_STORAGE_DOMAIN")}`,
},
{
protocol: "https",
hostname: "*.googleusercontent.com",
},
],
},
experimental: {
instrumentationHook: true,

View File

@@ -1 +1 @@
window.__ENV = {"NEXT_PUBLIC_UMAMI_ID":"aaed1f55-25e2-4223-b918-e429c390be35","NEXT_PUBLIC_KAN_ENV":"cloud","NEXT_PUBLIC_BASE_URL":"http://localhost:3000","NEXT_PUBLIC_AVATAR_BUCKET_NAME":"avatars","NEXT_PUBLIC_STORAGE_DOMAIN":"storage.kanbn.com","NEXT_PUBLIC_STORAGE_URL":"https://storage.kanbn.com"};
window.__ENV = {"NEXT_PUBLIC_UMAMI_ID":"aaed1f55-25e2-4223-b918-e429c390be35","NEXT_PUBLIC_KAN_ENV":"cloud","NEXT_PUBLIC_BASE_URL":"http://localhost:3000","NEXT_PUBLIC_AVATAR_BUCKET_NAME":"avatars","NEXT_PUBLIC_STORAGE_DOMAIN":"kanbn.com","NEXT_PUBLIC_STORAGE_URL":"https://storage.kanbn.com"};

View File

@@ -45,6 +45,10 @@ export const formatMemberDisplayName = (
return localPart.replace(/[_-]/g, ".");
};
export const getAvatarUrl = (key: string) => {
return `${env("NEXT_PUBLIC_STORAGE_URL")}/${env("NEXT_PUBLIC_AVATAR_BUCKET_NAME")}/${key}`;
export const getAvatarUrl = (imageOrKey: string) => {
if (imageOrKey.startsWith("http://") || imageOrKey.startsWith("https://")) {
return imageOrKey;
}
return `${env("NEXT_PUBLIC_STORAGE_URL")}/${env("NEXT_PUBLIC_AVATAR_BUCKET_NAME")}/${imageOrKey}`;
};

View File

@@ -578,14 +578,6 @@ export const cardRouter = createTRPCRouter({
>(),
)
.query(async ({ ctx, input }) => {
const userId = ctx.user?.id;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
const card = await cardRepo.getWorkspaceAndCardIdByCardPublicId(
ctx.db,
input.cardPublicId,
@@ -597,7 +589,17 @@ export const cardRouter = createTRPCRouter({
code: "NOT_FOUND",
});
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
if (card.workspaceVisibility === "private") {
const userId = ctx.user?.id;
if (!userId)
throw new TRPCError({
message: `User not authenticated`,
code: "UNAUTHORIZED",
});
await assertUserInWorkspace(ctx.db, userId, card.workspaceId);
}
const result = await cardRepo.getWithListAndMembersByPublicId(
ctx.db,

View File

@@ -239,6 +239,7 @@ export const getBySlug = async (
workspace: {
columns: {
publicId: true,
name: true,
slug: true,
},
},

View File

@@ -731,6 +731,7 @@ export const getWorkspaceAndCardIdByCardPublicId = async (
board: {
columns: {
workspaceId: true,
visibility: true,
},
},
},
@@ -742,6 +743,7 @@ export const getWorkspaceAndCardIdByCardPublicId = async (
? {
id: result.id,
workspaceId: result.list.board.workspaceId,
workspaceVisibility: result.list.board.visibility,
}
: null;
};