Skip to content

Commit caa059c

Browse files
committed
Edit Consumers
1 parent 87301c3 commit caa059c

File tree

3 files changed

+706
-0
lines changed

3 files changed

+706
-0
lines changed

src/routes/(protected)/consumers/+page.svelte

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,25 @@
163163
</p>
164164
</div>
165165
<div class="flex items-center gap-1.5 flex-shrink-0 ml-2">
166+
<a
167+
href="/consumers/{consumer.consumer_id}/edit"
168+
class="inline-flex items-center rounded border border-blue-300 bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 hover:bg-blue-100 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 dark:border-blue-600 dark:bg-blue-900/30 dark:text-blue-400 dark:hover:bg-blue-900/50"
169+
>
170+
<svg
171+
class="mr-1 h-3 w-3"
172+
fill="none"
173+
stroke="currentColor"
174+
viewBox="0 0 24 24"
175+
>
176+
<path
177+
stroke-linecap="round"
178+
stroke-linejoin="round"
179+
stroke-width="2"
180+
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"
181+
/>
182+
</svg>
183+
Edit
184+
</a>
166185
<a
167186
href="/consumers/{consumer.consumer_id}/rate-limits"
168187
class="inline-flex items-center rounded border border-gray-300 bg-white px-2 py-1 text-xs font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-1 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-300 dark:hover:bg-gray-600"
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
import { createLogger } from "$lib/utils/logger";
2+
import { obp_requests } from "$lib/obp/requests";
3+
import { extractErrorDetails } from "$lib/obp/errors";
4+
import { error, fail, redirect } from "@sveltejs/kit";
5+
import type { RequestEvent } from "@sveltejs/kit";
6+
import { SessionOAuthHelper } from "$lib/oauth/sessionHelper";
7+
8+
const logger = createLogger("EditConsumerServer");
9+
10+
interface Consumer {
11+
consumer_id: string;
12+
key?: string;
13+
secret?: string;
14+
app_name: string;
15+
app_type: string;
16+
description: string;
17+
developer_email: string;
18+
redirect_url: string;
19+
company: string;
20+
enabled: boolean;
21+
created: string;
22+
created_by_user?: {
23+
user_id: string;
24+
email: string;
25+
provider_id: string;
26+
provider: string;
27+
username: string;
28+
};
29+
}
30+
31+
interface Scope {
32+
scope_id: string;
33+
role_name: string;
34+
bank_id: string;
35+
}
36+
37+
interface Role {
38+
role: string;
39+
requires_bank_id: boolean;
40+
}
41+
42+
export async function load(event: RequestEvent) {
43+
const session = event.locals.session;
44+
45+
if (!session?.data?.user) {
46+
throw error(401, "Unauthorized");
47+
}
48+
49+
const sessionOAuth = SessionOAuthHelper.getSessionOAuth(session);
50+
const token = sessionOAuth?.accessToken;
51+
52+
if (!token) {
53+
throw error(401, "Unauthorized: No access token found in session.");
54+
}
55+
56+
const consumerId = event.params.consumer_id;
57+
58+
if (!consumerId) {
59+
throw error(400, "Consumer ID is required.");
60+
}
61+
62+
let consumer: Consumer | undefined = undefined;
63+
let scopes: Scope[] = [];
64+
let availableRoles: Role[] = [];
65+
let banks: Array<{ bank_id: string; short_name: string }> = [];
66+
67+
// Fetch consumer details
68+
try {
69+
consumer = await obp_requests.get(
70+
`/obp/v6.0.0/management/consumers/${consumerId}`,
71+
token,
72+
);
73+
logger.debug(`Retrieved consumer: ${consumer?.app_name}`);
74+
} catch (e) {
75+
logger.error("Error fetching consumer:", e);
76+
throw error(404, "Consumer not found.");
77+
}
78+
79+
if (!consumer) {
80+
throw error(404, "Consumer not found.");
81+
}
82+
83+
// Fetch scopes for this consumer
84+
try {
85+
const scopesResponse = await obp_requests.get(
86+
`/obp/v6.0.0/consumers/${consumerId}/scopes`,
87+
token,
88+
);
89+
scopes = scopesResponse?.list || [];
90+
logger.debug(`Retrieved ${scopes.length} scopes for consumer`);
91+
} catch (e) {
92+
logger.error("Error fetching scopes:", e);
93+
// Non-fatal - continue without scopes
94+
}
95+
96+
// Fetch available roles
97+
try {
98+
const rolesResponse = await obp_requests.get(
99+
`/obp/v6.0.0/roles`,
100+
token,
101+
);
102+
availableRoles = rolesResponse?.roles || [];
103+
logger.debug(`Retrieved ${availableRoles.length} available roles`);
104+
} catch (e) {
105+
logger.error("Error fetching roles:", e);
106+
// Non-fatal - continue without roles
107+
}
108+
109+
// Fetch banks for bank_id dropdown
110+
try {
111+
const banksResponse = await obp_requests.get(
112+
`/obp/v6.0.0/banks`,
113+
token,
114+
);
115+
banks = (banksResponse?.banks || []).map((b: any) => ({
116+
bank_id: b.bank_id,
117+
short_name: b.short_name || b.bank_id,
118+
}));
119+
logger.debug(`Retrieved ${banks.length} banks`);
120+
} catch (e) {
121+
logger.error("Error fetching banks:", e);
122+
// Non-fatal - continue without banks
123+
}
124+
125+
return {
126+
consumer,
127+
scopes,
128+
availableRoles,
129+
banks,
130+
};
131+
}
132+
133+
export const actions = {
134+
// Action to enable/disable consumer
135+
toggleEnabled: async (event: RequestEvent) => {
136+
const session = event.locals.session;
137+
138+
if (!session?.data?.user) {
139+
return fail(401, { error: "Unauthorized" });
140+
}
141+
142+
const sessionOAuth = SessionOAuthHelper.getSessionOAuth(session);
143+
const token = sessionOAuth?.accessToken;
144+
145+
if (!token) {
146+
return fail(401, { error: "Unauthorized: No access token found in session." });
147+
}
148+
149+
const consumerId = event.params.consumer_id;
150+
151+
if (!consumerId) {
152+
return fail(400, { error: "Consumer ID is required." });
153+
}
154+
155+
const formData = await event.request.formData();
156+
const enabled = formData.get("enabled") === "true";
157+
158+
try {
159+
logger.info(`Setting consumer ${consumerId} enabled=${enabled}`);
160+
161+
await obp_requests.put(
162+
`/obp/v6.0.0/management/consumers/${consumerId}`,
163+
{ enabled },
164+
token,
165+
);
166+
167+
logger.info(`Successfully updated consumer ${consumerId} enabled status`);
168+
169+
return { success: true, action: "toggleEnabled" };
170+
} catch (e: any) {
171+
logger.error("Error updating consumer:", e);
172+
const { message } = extractErrorDetails(e);
173+
return fail(500, { error: message, action: "toggleEnabled" });
174+
}
175+
},
176+
177+
// Action to add a scope
178+
addScope: async (event: RequestEvent) => {
179+
const session = event.locals.session;
180+
181+
if (!session?.data?.user) {
182+
return fail(401, { error: "Unauthorized" });
183+
}
184+
185+
const sessionOAuth = SessionOAuthHelper.getSessionOAuth(session);
186+
const token = sessionOAuth?.accessToken;
187+
188+
if (!token) {
189+
return fail(401, { error: "Unauthorized: No access token found in session." });
190+
}
191+
192+
const consumerId = event.params.consumer_id;
193+
194+
if (!consumerId) {
195+
return fail(400, { error: "Consumer ID is required." });
196+
}
197+
198+
const formData = await event.request.formData();
199+
const role_name = formData.get("role_name") as string;
200+
const bank_id = formData.get("bank_id") as string || "";
201+
202+
if (!role_name) {
203+
return fail(400, { error: "Role name is required.", action: "addScope" });
204+
}
205+
206+
try {
207+
logger.info(`Adding scope ${role_name} to consumer ${consumerId}`);
208+
209+
await obp_requests.post(
210+
`/obp/v6.0.0/consumers/${consumerId}/scopes`,
211+
{ role_name, bank_id },
212+
token,
213+
);
214+
215+
logger.info(`Successfully added scope to consumer ${consumerId}`);
216+
217+
return { success: true, action: "addScope" };
218+
} catch (e: any) {
219+
logger.error("Error adding scope:", e);
220+
const { message } = extractErrorDetails(e);
221+
return fail(500, { error: message, action: "addScope" });
222+
}
223+
},
224+
225+
// Action to delete a scope
226+
deleteScope: async (event: RequestEvent) => {
227+
const session = event.locals.session;
228+
229+
if (!session?.data?.user) {
230+
return fail(401, { error: "Unauthorized" });
231+
}
232+
233+
const sessionOAuth = SessionOAuthHelper.getSessionOAuth(session);
234+
const token = sessionOAuth?.accessToken;
235+
236+
if (!token) {
237+
return fail(401, { error: "Unauthorized: No access token found in session." });
238+
}
239+
240+
const consumerId = event.params.consumer_id;
241+
242+
if (!consumerId) {
243+
return fail(400, { error: "Consumer ID is required." });
244+
}
245+
246+
const formData = await event.request.formData();
247+
const scope_id = formData.get("scope_id") as string;
248+
249+
if (!scope_id) {
250+
return fail(400, { error: "Scope ID is required.", action: "deleteScope" });
251+
}
252+
253+
try {
254+
logger.info(`Deleting scope ${scope_id} from consumer ${consumerId}`);
255+
256+
await obp_requests.delete(
257+
`/obp/v6.0.0/consumers/${consumerId}/scope/${scope_id}`,
258+
token,
259+
);
260+
261+
logger.info(`Successfully deleted scope from consumer ${consumerId}`);
262+
263+
return { success: true, action: "deleteScope" };
264+
} catch (e: any) {
265+
logger.error("Error deleting scope:", e);
266+
const { message } = extractErrorDetails(e);
267+
return fail(500, { error: message, action: "deleteScope" });
268+
}
269+
},
270+
};

0 commit comments

Comments
 (0)