Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,7 @@ REFRESH_TOKEN_SECRET=e628d7938c76308774cecf87dcb9bee6b8cae80ed2d20731ef94e211cf9
EMAIL_ID=your-email@gmail.com
# Your password from: https://myaccount.google.com/apppasswords
EMAIL_PASSWORD="aaaa bbbb cccc dddd"

# Encryption Settings
ENCRYPTION_ALGORITHM=YOUR_ENCRYPTION_ALGORITHM
ENCRYPTION_PASSWORD=YOUR_ENCRYPTION_PASSWORD
4 changes: 4 additions & 0 deletions .env.prod
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ REFRESH_TOKEN_SECRET=e628d7938c76308774cecf87dcb9bee6b8cae80ed2d20731ef94e211cf9
EMAIL_ID=your-email@gmail.com
# Your password from: https://myaccount.google.com/apppasswords
EMAIL_PASSWORD="aaaa bbbb cccc dddd"

# Encryption Settings
ENCRYPTION_ALGORITHM=YOUR_ENCRYPTION_ALGORITHM
ENCRYPTION_PASSWORD=YOUR_ENCRYPTION_PASSWORD
2 changes: 2 additions & 0 deletions Clients/env.vars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ export const ENV_VARs = {
: "http://localhost:3000/"), // final Node/SSR fallback
IS_DEMO_APP: import.meta.env.VITE_IS_DEMO_APP === "true",
IS_MULTI_TENANT: import.meta.env.VITE_IS_MULTI_TENANT === "true",
CLIENT_ID: import.meta.env.VITE_CLIENT_ID,
SLACK_URL: import.meta.env.VITE_SLACK_URL,
};
4 changes: 4 additions & 0 deletions Clients/src/application/constants/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ const allowedRoles = {
edit: ["Admin", "Editor"],
delete: ["Admin", "Editor"],
},
slack: {
view: ["Admin"],
manage: ["Admin"],
},
Comment thread
rachanabasnet marked this conversation as resolved.
};

export default allowedRoles;
87 changes: 87 additions & 0 deletions Clients/src/application/hooks/useSlackIntegrations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { useEffect, useState } from "react";
import { getSlackIntegrations } from "../repository/slack.integration.repository";

interface ISlackWebhook {
id?: number;
access_token_iv?: string;
access_token: string;
scope: string;
user_id?: number; // FK to users table
team_name: string;
team_id: string;
channel: string;
channel_id: string;
configuration_url: string; // configuration URL to manage the webhook
url_iv?: string;
url: string; // URL of the slack workspace
created_at?: string;
is_active?: boolean;
}
export interface SlackWebhook {
id?: number;
scope: string;
teamName: string;
teamId: string;
channel: string;
channelId: string;
createdAt?: string;
isActive?: boolean;
}

interface ApiResponse {
data: ISlackWebhook[];
}

const useSlackIntegrations = (userId: number | null) => {
const [slackIntegrations, setSlackIntegrations] = useState<SlackWebhook[]>(
[],
);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);

const fetchSlackIntegrations = async () => {
try {
const controller = new AbortController();
const signal = controller.signal;
setLoading(true);
const response = await getSlackIntegrations({ id: userId!, signal });

const integrations: SlackWebhook[] = (response as ApiResponse).data.map(
(item: ISlackWebhook): SlackWebhook => ({
Comment thread
rachanabasnet marked this conversation as resolved.
id: item.id,
scope: item.scope,
teamName: item.team_name,
teamId: item.team_id,
channel: item.channel,
channelId: item.channel_id,
createdAt: item.created_at,
isActive: item.is_active,
}),
);

setSlackIntegrations(integrations);
setError(null);
} catch (err) {
setError(
err instanceof Error
? err.message
: "Failed to fetch slack integrations",
);
} finally {
setLoading(false);
}
};

useEffect(() => {
fetchSlackIntegrations();
}, []);

return {
slackIntegrations,
loading,
error,
refreshSlackIntegrations: fetchSlackIntegrations,
};
};

export default useSlackIntegrations;
68 changes: 68 additions & 0 deletions Clients/src/application/repository/slack.integration.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { apiServices } from "../../infrastructure/api/networkServices";

export async function getSlackIntegrations({
id,
channel,
signal,
responseType = "json",
}: {
id: number;
channel?: string;
signal?: AbortSignal;
responseType?: string;
}): Promise<any> {
const response = await apiServices.get(`/slackWebhooks`, {
userId: id,
channel,
signal,
responseType,
});
return response.data;
}

export async function getSlackIntegrationById({
id,
signal,
responseType = "json",
}: {
id: string;
signal?: AbortSignal;
responseType?: string;
}): Promise<any> {
const response = await apiServices.get(`/slackWebhooks/${id}`, {
signal,
responseType,
});
return response.data;
}

export async function createSlackIntegration({
body,
}: {
body: any;
}): Promise<any> {
const response = await apiServices.post("/slackWebhooks", body);
return response.data;
}

export async function updateSlackIntegration({
id,
body,
}: {
id: string;
body: any;
}): Promise<any> {
const response = await apiServices.patch(`/slackWebhooks/${id}`, body);
return response;
}

export async function sendSlackMessage({
id,
body,
}: {
id: number;
body: { title: string; message: string };
}): Promise<any> {
const response = await apiServices.post(`/slackWebhooks/${id}/send`, body);
return response.data;
}
Loading