celestya 0.0.5 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,36 +17,61 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
19
  };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
 
20
30
  // src/index.ts
21
31
  var src_exports = {};
22
32
  __export(src_exports, {
23
- Proxy: () => Proxy2,
24
- apiFetch: () => apiFetch,
25
- debug: () => debug2,
26
- getSession: () => getSession
33
+ CelestyaProxy: () => CelestyaProxy,
34
+ attemptTokenRefresh: () => attemptTokenRefresh,
35
+ err: () => err,
36
+ getSession: () => getSession,
37
+ ok: () => ok,
38
+ serverAPIWrapper: () => serverAPIWrapper,
39
+ serverSideFetch: () => serverSideFetch
27
40
  });
28
41
  module.exports = __toCommonJS(src_exports);
29
42
 
30
- // src/server/api.ts
31
- var import_cache = require("next/cache");
32
-
33
- // src/server/errors.ts
34
- var requestError = () => Response.json({
35
- error: "requestError",
36
- message: "error while sending request through proxy"
37
- });
38
- var invalidEndpoint = () => Response.json({
39
- error: "invalidEndpoint",
40
- message: "invalid endpoint"
41
- });
42
- var sessionError = () => Response.json({
43
- error: "noSession",
44
- message: "no session found"
45
- });
43
+ // src/types/response.ts
44
+ var Ok = class {
45
+ constructor(value) {
46
+ this.value = value;
47
+ }
48
+ isOk() {
49
+ return true;
50
+ }
51
+ isErr() {
52
+ return false;
53
+ }
54
+ };
55
+ var Err = class {
56
+ constructor(error) {
57
+ this.error = error;
58
+ }
59
+ isOk() {
60
+ return false;
61
+ }
62
+ isErr() {
63
+ return true;
64
+ }
65
+ };
66
+ function ok(value) {
67
+ return new Ok(value);
68
+ }
69
+ function err(error) {
70
+ return new Err(error);
71
+ }
46
72
 
47
73
  // src/server/api.ts
74
+ var import_cache = require("next/cache");
48
75
  var import_jwt_decode = require("jwt-decode");
49
76
 
50
77
  // src/server/session.ts
@@ -53,21 +80,155 @@ var import_headers = require("next/headers");
53
80
  var sessionOptions = {
54
81
  password: process.env.CELESTYA_SECRET || "PLEASE_SET_PASSWORD",
55
82
  cookieName: process.env.CELESTYA_COOKIE_NAME || "PLEASE_SET_COOKIE_NAME",
56
- cookieOptions: { secure: process.env.SECURE === "true" || false }
83
+ cookieOptions: { secure: process.env.SECURE === "true" }
57
84
  };
58
- var getSessionServerside = async () => {
85
+ var getSession = async (sessionOpts) => {
86
+ if (sessionOpts === void 0 && (!process.env.CELESTYA_SECRET || !process.env.CELESTYA_COOKIE_NAME)) {
87
+ throw new Error(
88
+ "CELESTYA_SECRET and CELESTYA_COOKIE_NAME must be set in environment variables."
89
+ );
90
+ }
59
91
  const session = await (0, import_iron_session.getIronSession)(
60
- (0, import_headers.cookies)(),
61
- sessionOptions
92
+ await (0, import_headers.cookies)(),
93
+ sessionOpts || sessionOptions
62
94
  );
63
95
  return session;
64
96
  };
65
- var session_default = getSessionServerside;
97
+
98
+ // src/server/fetch.ts
99
+ var refreshPromise = null;
100
+ var serverSideFetch = async ({
101
+ url,
102
+ method = "GET",
103
+ config,
104
+ body,
105
+ sessionIsOptional = false,
106
+ skipRefresh = false,
107
+ ...options
108
+ }) => {
109
+ const headers = new Headers({
110
+ "Content-Type": "application/json",
111
+ ...options.headers
112
+ });
113
+ const session = await getSession();
114
+ if (session.token !== void 0) {
115
+ headers.set("Authorization", `Bearer ${session.token.jwt}`);
116
+ } else if (!sessionIsOptional) {
117
+ return err({
118
+ error: "SESSION_ERROR",
119
+ message: "Session is required but not found."
120
+ });
121
+ }
122
+ const opts = {
123
+ method,
124
+ headers,
125
+ ...options
126
+ };
127
+ try {
128
+ if (body) opts.body = JSON.stringify(body);
129
+ } catch (e) {
130
+ console.log("Error stringifying body: ", e);
131
+ }
132
+ try {
133
+ const response = await fetch(`${config.apiUrl}${url}`, opts);
134
+ if (response.status === 401 && !skipRefresh && !sessionIsOptional) {
135
+ if (config.debug)
136
+ console.log("#> 401 detected, attempting token refresh");
137
+ let currentRefresh;
138
+ if (refreshPromise === null) {
139
+ refreshPromise = attemptTokenRefresh(config).finally(() => {
140
+ refreshPromise = null;
141
+ });
142
+ currentRefresh = refreshPromise;
143
+ } else {
144
+ if (config.debug)
145
+ console.log("#> Refresh already in progress, waiting...");
146
+ currentRefresh = refreshPromise;
147
+ }
148
+ const refreshResult = await currentRefresh;
149
+ if (refreshResult.isOk()) {
150
+ return serverSideFetch({
151
+ url,
152
+ method,
153
+ config,
154
+ body,
155
+ sessionIsOptional,
156
+ skipRefresh: true,
157
+ // Prevent infinite loop
158
+ ...options
159
+ });
160
+ }
161
+ return err(refreshResult.error);
162
+ }
163
+ if (!response.ok) {
164
+ return err({
165
+ error: "RESPONSE_ERROR",
166
+ message: `HTTP error! status: ${response.status}`
167
+ });
168
+ }
169
+ try {
170
+ const res = await response.json();
171
+ if (res.error !== void 0) {
172
+ return err(res);
173
+ }
174
+ return ok(res);
175
+ } catch (e) {
176
+ return err({
177
+ error: "PARSE_ERROR",
178
+ message: "Failed to parse response as JSON"
179
+ });
180
+ }
181
+ } catch (e) {
182
+ return err({
183
+ error: "FETCH_ERROR",
184
+ message: "Failed to fetch the resource: " + String(e)
185
+ });
186
+ }
187
+ };
188
+ async function attemptTokenRefresh(config) {
189
+ var _a;
190
+ if (config.debug) console.log("#> attemptTokenRefresh called");
191
+ const { jwtDecode: jwtDecode2 } = await import("jwt-decode");
192
+ const session = await getSession();
193
+ if (!((_a = session.token) == null ? void 0 : _a.refresh)) {
194
+ return err({
195
+ error: "NO_REFRESH_TOKEN",
196
+ message: "No refresh token available in session"
197
+ });
198
+ }
199
+ const res = await serverSideFetch({
200
+ method: "POST",
201
+ url: "/refresh",
202
+ body: {
203
+ refreshToken: session.token.refresh
204
+ },
205
+ sessionIsOptional: true,
206
+ skipRefresh: true,
207
+ // Prevent infinite loop
208
+ config
209
+ });
210
+ if (config.debug) console.log("#> attemptTokenRefresh", res);
211
+ if (res.isErr()) {
212
+ session.destroy();
213
+ return err(res.error);
214
+ }
215
+ const decoded = jwtDecode2(res.value.data.token);
216
+ const newToken = {
217
+ jwt: res.value.data.token,
218
+ refresh: session.token.refresh,
219
+ // Keep the same refresh token
220
+ decoded
221
+ };
222
+ session.token = newToken;
223
+ await session.save();
224
+ return ok({ data: "success" });
225
+ }
66
226
 
67
227
  // src/server/api.ts
68
228
  var rHandler = {
69
229
  GET: {
70
230
  user: ({ request, config }) => getUser(request, config),
231
+ refresh: ({ request, config }) => refresh(request, config),
71
232
  logout: ({ config }) => logout(config),
72
233
  debug: () => debug(),
73
234
  oauth: ({ request, config }) => oauth(request, config),
@@ -82,38 +243,48 @@ var rHandler = {
82
243
  proxy: ({ request, config, options }) => proxyFunction("DELETE", request, config, options)
83
244
  }
84
245
  };
85
- async function proxy(method, request, options, config) {
246
+ async function Proxy2(method, request, options, config) {
86
247
  try {
248
+ const params = await options.params;
87
249
  const parameters = {
88
250
  request,
89
- path: options.params.endpoint[0] || request.nextUrl.pathname.replace(config.route, ""),
90
- options: options.params.endpoint,
251
+ path: params.endpoint[0] || request.nextUrl.pathname.replace(config.route, ""),
252
+ options: params.endpoint,
91
253
  config
92
254
  };
93
255
  if (config.debug) console.log("#> proxy:", parameters);
94
256
  if (rHandler[method][parameters.path])
95
257
  return await rHandler[method][parameters.path](parameters);
96
- return invalidEndpoint();
258
+ return Response.json({
259
+ error: "INVALID_ENDPOINT",
260
+ message: "the provided endpoint is not valid"
261
+ });
97
262
  } catch (e) {
98
263
  console.log("#> proxyError:", e);
99
- return requestError();
264
+ Response.json({
265
+ error: "REQUEST_ERROR",
266
+ message: "error while sending request through frontend-backend proxy"
267
+ });
100
268
  }
101
269
  }
102
270
  async function login(request, config) {
103
- const session = await session_default();
104
271
  const formData = await request.json();
105
- const response = await fetch(`${config.apiUrl}/login`, {
272
+ const res = await serverSideFetch({
106
273
  method: "POST",
107
- headers: { "Content-Type": "application/json" },
108
- body: JSON.stringify(formData)
274
+ url: "/login",
275
+ body: formData,
276
+ sessionIsOptional: true,
277
+ config
109
278
  });
110
- const res = await response.json();
111
279
  if (config.debug) console.log("#> login", res);
112
- if (res.error) return Response.json(res);
113
- const dec = (0, import_jwt_decode.jwtDecode)(res.data.token);
280
+ if (res.isErr()) {
281
+ return Response.json(res.error);
282
+ }
283
+ const dec = (0, import_jwt_decode.jwtDecode)(res.value.data.token);
284
+ const session = await getSession();
114
285
  session.token = {
115
- jwt: res.data.token,
116
- refresh: res.data.refresh || "refresh_token",
286
+ jwt: res.value.data.token,
287
+ refresh: res.value.data.refresh || "refresh_token",
117
288
  decoded: dec
118
289
  };
119
290
  await session.save();
@@ -122,27 +293,26 @@ async function login(request, config) {
122
293
  });
123
294
  }
124
295
  async function getUser(request, config) {
125
- const session = await session_default();
126
- if (!session || !session.token) return sessionError();
127
- const force = request.nextUrl.searchParams.get("force") == "true";
128
- if (session.user && !force)
296
+ const session = await getSession();
297
+ if (session.token === void 0)
298
+ return Response.json({
299
+ error: "SESSION_ERROR",
300
+ message: "Session is required but not found."
301
+ });
302
+ const force = request.nextUrl.searchParams.get("force") === "true";
303
+ if (session.user !== void 0 && !force)
129
304
  return Response.json({
130
305
  data: session.user
131
306
  });
132
- const response = await fetch(
133
- `${config.apiUrl}${config.userEndpoint}`,
134
- {
135
- method: "GET",
136
- headers: {
137
- "Content-Type": "application/json",
138
- Authorization: "Bearer " + session.token.jwt
139
- }
140
- }
141
- );
142
- const res = await response.json();
307
+ const res = await serverSideFetch({
308
+ url: `${config.userEndpoint}`,
309
+ config
310
+ });
143
311
  if (config.debug) console.log("#> getUser", res);
144
- if (res.error) return Response.json(res);
145
- session.user = res.data;
312
+ if (res.isErr()) {
313
+ return Response.json(res.error);
314
+ }
315
+ session.user = res.value.data;
146
316
  await session.save();
147
317
  return Response.json({
148
318
  data: session.user
@@ -150,43 +320,44 @@ async function getUser(request, config) {
150
320
  }
151
321
  async function oauth(request, config) {
152
322
  const authUrl = request.nextUrl.searchParams.get("authUrl");
323
+ const state = request.nextUrl.searchParams.get("state");
153
324
  if (!authUrl) throw new Error("No authUrl provided");
154
325
  const url = new URL(config.route + "/oauth_callback", config.host);
155
- const state = request.nextUrl.searchParams.get("state");
156
326
  if (state) url.searchParams.set("state", state);
157
- const response = await fetch(
158
- `${config.apiUrl}${authUrl}?returnUrl=${encodeURIComponent(
159
- url.toString()
160
- )}`
161
- );
162
- const res = await response.json();
163
- if (config.debug) console.log("#> oauth", res);
164
- if (res.error) return Response.json(res);
165
- return Response.json({
166
- data: res.data
327
+ const oAuthUrl = new URL(authUrl, config.apiUrl);
328
+ oAuthUrl.searchParams.set("returnUrl", url.toString());
329
+ const res = await serverSideFetch({
330
+ url: oAuthUrl.pathname + oAuthUrl.search,
331
+ config,
332
+ sessionIsOptional: true
167
333
  });
334
+ if (res.isErr()) {
335
+ if (config.debug) console.log("#> oauthError", res.error);
336
+ return Response.json(res.error);
337
+ }
338
+ return Response.json(res.value);
168
339
  }
169
340
  async function oauth_callback(request, config) {
170
- const session = await session_default();
341
+ const refresh2 = request.nextUrl.searchParams.get("refresh");
171
342
  const token = request.nextUrl.searchParams.get("token");
172
- const refresh = request.nextUrl.searchParams.get("refresh");
173
- const state = request.nextUrl.searchParams.get("state");
174
- if (!token) throw new Error("No token provided");
343
+ if (token === null) throw new Error("No token provided");
175
344
  const dec = (0, import_jwt_decode.jwtDecode)(token);
345
+ const session = await getSession();
176
346
  session.token = {
177
347
  jwt: token,
178
- refresh: refresh || "refresh_token",
348
+ refresh: refresh2 || "refresh_token",
179
349
  decoded: dec
180
350
  };
181
351
  await session.save();
182
- if (state)
352
+ const state = request.nextUrl.searchParams.get("state");
353
+ if (state !== null)
183
354
  return Response.redirect(
184
355
  state.includes("http") ? state : config.host + state
185
356
  );
186
357
  return Response.redirect(config.host);
187
358
  }
188
359
  async function logout(config) {
189
- const session = await session_default();
360
+ const session = await getSession();
190
361
  session.destroy();
191
362
  (0, import_cache.revalidatePath)(config.host, "layout");
192
363
  return Response.json({
@@ -194,63 +365,63 @@ async function logout(config) {
194
365
  });
195
366
  }
196
367
  async function debug() {
197
- const session = await session_default();
198
- return Response.json(session);
368
+ return Response.json(await getSession());
369
+ }
370
+ async function refresh(request, config) {
371
+ const result = await attemptTokenRefresh(config);
372
+ if (config.debug) console.log("#> refresh result", result);
373
+ if (result.isErr()) {
374
+ return Response.json(result.error, { status: 401 });
375
+ }
376
+ const url = request.nextUrl;
377
+ url.pathname = decodeURIComponent(url.searchParams.get("r") || "");
378
+ url.searchParams.delete("r");
379
+ return Response.redirect(url);
199
380
  }
200
381
  async function proxyFunction(method, request, config, options) {
201
- var _a;
202
- const session = await session_default();
203
- const opts = {
204
- method,
205
- headers: {
206
- "Content-Type": "application/json",
207
- Authorization: "Bearer " + ((_a = session.token) == null ? void 0 : _a.jwt)
208
- }
209
- };
210
- if (method === "POST") opts.body = JSON.stringify(await request.json());
211
382
  options.shift();
212
- const response = await fetch(
213
- `${config.apiUrl}/${options.join("/")}${request.nextUrl.search}`,
214
- opts
215
- );
216
- const res = await response.json();
217
- if (config.debug) console.log("#> getProxyFunction", res);
218
- return Response.json(res);
383
+ const res = await serverSideFetch({
384
+ method,
385
+ url: `/${options.join("/")}${request.nextUrl.search}`,
386
+ body: method === "POST" ? await request.json() : void 0,
387
+ config
388
+ });
389
+ if (config.debug) console.log("#> proxyFunction", res);
390
+ if (res.isErr()) {
391
+ return Response.json(res.error);
392
+ }
393
+ return Response.json(res.value);
219
394
  }
220
395
 
221
- // src/server/fetch.ts
222
- var serverSideFetch = async (url, options, config) => {
223
- var _a;
224
- const session = await session_default();
225
- const opts = {
226
- method: options.method || "GET",
227
- headers: {
228
- "Content-Type": "application/json",
229
- Authorization: "Bearer " + ((_a = session.token) == null ? void 0 : _a.jwt)
230
- }
396
+ // src/server/index.ts
397
+ var CelestyaProxy = (config) => {
398
+ return {
399
+ POST: (req, opt) => Proxy2("POST", req, opt, config),
400
+ GET: (req, opt) => Proxy2("GET", req, opt, config),
401
+ DELETE: (req, opt) => Proxy2("DELETE", req, opt, config)
231
402
  };
232
- if (options.body) opts.body = JSON.stringify(options.body);
233
- const response = await fetch(`${config.apiUrl}${url}`, opts);
234
- const res = await response.json();
235
- return res;
236
403
  };
237
404
 
238
- // src/server/test.ts
239
- var Debug = () => {
240
- console.log("#> sessionOptions: ", sessionOptions);
405
+ // src/server/wrapper.ts
406
+ var serverAPIWrapper = (apiWrapper, config) => {
407
+ return apiWrapper(async (data) => {
408
+ const { method, url, body } = data;
409
+ return serverSideFetch({
410
+ url,
411
+ method,
412
+ body,
413
+ config
414
+ });
415
+ });
241
416
  };
242
- var test_default = Debug;
243
-
244
- // src/index.ts
245
- var Proxy2 = proxy;
246
- var getSession = session_default;
247
- var debug2 = test_default;
248
- var apiFetch = serverSideFetch;
249
417
  // Annotate the CommonJS export names for ESM import in node:
250
418
  0 && (module.exports = {
251
- Proxy,
252
- apiFetch,
253
- debug,
254
- getSession
419
+ CelestyaProxy,
420
+ attemptTokenRefresh,
421
+ err,
422
+ getSession,
423
+ ok,
424
+ serverAPIWrapper,
425
+ serverSideFetch
255
426
  });
256
427
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/server/api.ts","../src/server/errors.ts","../src/server/session.ts","../src/server/fetch.ts","../src/server/test.ts"],"sourcesContent":["import proxy from \"./server/api\";\nimport { serverSideFetch } from \"./server/fetch\";\nimport getSessionServerside from \"./server/session\";\nimport Debug from \"./server/test\";\n\nexport const Proxy = proxy;\nexport const getSession = getSessionServerside;\nexport const debug = Debug;\nexport const apiFetch = serverSideFetch;\n\nimport { IConfig, IRequestOptions, Session } from \"./types\";\n\nexport { IConfig, IRequestOptions, Session };\n","import { NextRequest } from \"next/server\";\nimport { revalidatePath } from \"next/cache\";\nimport { requestError } from \"./errors\";\nimport { invalidEndpoint, sessionError } from \"./errors\";\nimport { jwtDecode } from \"jwt-decode\";\nimport { IConfig, IRequestOptions, RouteHandler } from \"../types\";\nimport getSessionServerside from \"./session\";\n\nconst rHandler: RouteHandler = {\n GET: {\n user: ({ request, config }) => getUser(request, config),\n logout: ({ config }) => logout(config),\n debug: () => debug(),\n oauth: ({ request, config }) => oauth(request, config),\n oauth_callback: ({ request, config }) =>\n oauth_callback(request, config),\n proxy: ({ request, config, options }) =>\n proxyFunction(\"GET\", request, config, options),\n },\n POST: {\n login: ({ request, config }) => login(request, config),\n proxy: ({ request, config, options }) =>\n proxyFunction(\"POST\", request, config, options),\n },\n DELETE: {\n proxy: ({ request, config, options }) =>\n proxyFunction(\"DELETE\", request, config, options),\n },\n};\n\nexport default async function proxy(\n method: string,\n request: NextRequest,\n options: IRequestOptions,\n config: IConfig\n) {\n try {\n const parameters = {\n request,\n path:\n options.params.endpoint[0] ||\n request.nextUrl.pathname.replace(config.route, \"\"),\n options: options.params.endpoint,\n config,\n };\n\n if (config.debug) console.log(\"#> proxy:\", parameters);\n\n //console.log(`[${method}]: /${parameters.path}`);\n\n if (rHandler[method][parameters.path])\n return await rHandler[method][parameters.path](parameters);\n\n return invalidEndpoint();\n } catch (e) {\n console.log(\"#> proxyError:\", e);\n return requestError();\n }\n}\n\nasync function login(request: NextRequest, config: IConfig) {\n const session = await getSessionServerside();\n const formData = await request.json();\n\n const response: Response = await fetch(`${config.apiUrl}/login`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(formData),\n });\n\n const res = await response.json();\n\n if (config.debug) console.log(\"#> login\", res);\n\n if (res.error) return Response.json(res);\n\n const dec: any = jwtDecode(res.data.token);\n\n session.token = {\n jwt: res.data.token,\n refresh: res.data.refresh || \"refresh_token\",\n decoded: dec,\n };\n\n await session.save();\n\n return Response.json({\n redirect: \"/\",\n });\n}\n\nasync function getUser(request: NextRequest, config: IConfig) {\n const session = await getSessionServerside<any>();\n\n if (!session || !session.token) return sessionError();\n\n const force = request.nextUrl.searchParams.get(\"force\") == \"true\";\n\n // * User already exists in session\n if (session.user && !force)\n return Response.json({\n data: session.user,\n });\n\n // * User does not exist in session\n const response: Response = await fetch(\n `${config.apiUrl}${config.userEndpoint}`,\n {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + session.token.jwt,\n },\n }\n );\n\n const res = await response.json();\n\n if (config.debug) console.log(\"#> getUser\", res);\n\n if (res.error) return Response.json(res);\n\n session.user = res.data;\n\n await session.save();\n\n return Response.json({\n data: session.user,\n });\n}\n\nasync function oauth(request: NextRequest, config: IConfig) {\n const authUrl = request.nextUrl.searchParams.get(\"authUrl\");\n\n if (!authUrl) throw new Error(\"No authUrl provided\");\n\n const url = new URL(config.route + \"/oauth_callback\", config.host);\n\n const state = request.nextUrl.searchParams.get(\"state\");\n if (state) url.searchParams.set(\"state\", state);\n\n const response: Response = await fetch(\n `${config.apiUrl}${authUrl}?returnUrl=${encodeURIComponent(\n url.toString()\n )}`\n );\n\n const res = await response.json();\n\n if (config.debug) console.log(\"#> oauth\", res);\n\n if (res.error) return Response.json(res);\n\n return Response.json({\n data: res.data,\n });\n}\n\nasync function oauth_callback(request: NextRequest, config: IConfig) {\n const session = await getSessionServerside();\n const token = request.nextUrl.searchParams.get(\"token\");\n const refresh = request.nextUrl.searchParams.get(\"refresh\");\n const state = request.nextUrl.searchParams.get(\"state\");\n\n if (!token) throw new Error(\"No token provided\");\n\n const dec: any = jwtDecode(token);\n\n session.token = {\n jwt: token,\n refresh: refresh || \"refresh_token\",\n decoded: dec,\n };\n\n await session.save();\n\n if (state)\n return Response.redirect(\n state.includes(\"http\") ? state : config.host + state\n );\n\n return Response.redirect(config.host);\n}\n\nasync function logout(config: IConfig) {\n const session = await getSessionServerside();\n\n session.destroy();\n\n revalidatePath(config.host, \"layout\");\n\n //return Response.redirect(config.host);\n\n return Response.json({\n redirect: \"/\",\n });\n}\n\nasync function debug() {\n const session = await getSessionServerside();\n\n return Response.json(session);\n}\n\n// TODO: add refresh logic\n\nasync function proxyFunction(\n method: string,\n request: NextRequest,\n config: IConfig,\n options: string[]\n) {\n const session = await getSessionServerside();\n\n const opts: RequestInit = {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + session.token?.jwt,\n },\n };\n\n if (method === \"POST\") opts.body = JSON.stringify(await request.json());\n\n options.shift();\n const response: Response = await fetch(\n `${config.apiUrl}/${options.join(\"/\")}${request.nextUrl.search}`,\n opts\n );\n\n const res = await response.json();\n\n if (config.debug) console.log(\"#> getProxyFunction\", res);\n\n return Response.json(res);\n}\n","export const requestError = () =>\n Response.json({\n error: \"requestError\",\n message: \"error while sending request through proxy\",\n });\n\nexport const invalidEndpoint = () =>\n Response.json({\n error: \"invalidEndpoint\",\n message: \"invalid endpoint\",\n });\n\nexport const sessionError = () =>\n Response.json({\n error: \"noSession\",\n message: \"no session found\",\n });\n","import { SessionOptions } from \"iron-session\";\nimport { getIronSession } from \"iron-session\";\nimport { cookies } from \"next/headers\";\nimport { ServerSideSession } from \"../types/internal\";\nimport { Session } from \"../types\";\n\ndeclare module \"iron-session\" {\n interface IronSessionData<U, T> {\n user?: U;\n token?: {\n jwt: string;\n refresh: string;\n decoded: T;\n };\n }\n}\n\nexport interface DefaultUser {\n [key: string]: any;\n}\n\nexport interface Token {\n token: string;\n}\n\nexport const sessionOptions: SessionOptions = {\n password: process.env.CELESTYA_SECRET || \"PLEASE_SET_PASSWORD\",\n cookieName: process.env.CELESTYA_COOKIE_NAME || \"PLEASE_SET_COOKIE_NAME\",\n cookieOptions: { secure: process.env.SECURE === \"true\" || false },\n};\n\nconst getSessionServerside = async <U = DefaultUser>() => {\n const session: Session<U> = await getIronSession<ServerSideSession<U>>(\n cookies(),\n sessionOptions\n );\n\n return session;\n};\n\nexport default getSessionServerside;\n","import { IConfig, IServerSideRequestOptions } from \"../types\";\nimport getSessionServerside from \"./session\";\n\nexport const serverSideFetch = async (\n url: string,\n options: IServerSideRequestOptions,\n config: IConfig\n) => {\n const session = await getSessionServerside();\n\n const opts: RequestInit = {\n method: options.method || \"GET\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: \"Bearer \" + session.token?.jwt,\n },\n };\n\n if (options.body) opts.body = JSON.stringify(options.body);\n\n const response: Response = await fetch(`${config.apiUrl}${url}`, opts);\n\n const res = await response.json();\n\n return res;\n};\n","import { sessionOptions } from \"./session\";\n\nconst Debug = () => {\n console.log(\"#> sessionOptions: \", sessionOptions);\n};\n\nexport default Debug;\n"],"mappings":"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","names":["Proxy","debug","Proxy","debug"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/types/response.ts","../src/server/api.ts","../src/server/session.ts","../src/server/fetch.ts","../src/server/index.ts","../src/server/wrapper.ts"],"sourcesContent":["export {\n type IConfig,\n type IRequestOptions,\n type Session,\n type WrapperFunction,\n} from \"./types\";\nexport {\n type Result,\n type BaseError,\n type Ok,\n type Err,\n ok,\n err,\n} from \"./types/response\";\n\nexport { CelestyaProxy } from \"./server\";\nexport { serverSideFetch, attemptTokenRefresh } from \"./server/fetch\";\nexport { serverAPIWrapper } from \"./server/wrapper\";\nexport { getSession } from \"./server/session\";\n","export type BaseError = {\n error: string;\n message: string;\n};\n\nexport type Success<S> = {\n data: S;\n};\n\n/**\n * A Result type that represents either a successful value (Ok) or an error (Err).\n * This is a discriminated union type that helps handle errors in a type-safe way.\n *\n * @template T - The type of the successful value\n * @template E - The type of the error, must extend BaseError\n */\nexport type Result<T, E extends BaseError> = Ok<T, E> | Err<T, E>;\n\ntype IResult<T, E extends BaseError> = {\n /**\n * Checks if the `Result` is an `Ok` instance\n */\n isOk: () => this is Ok<T, E>;\n\n /**\n * Checks if the `Result` is an `Err` instance.\n */\n isErr: () => this is Err<T, E>;\n};\n\n/**\n * Represents a successful `Result` value.\n *\n * @template T - The type of the successful value.\n * @template E - The type of the error, must extend `BaseError`.\n */\nexport class Ok<T, E extends BaseError> implements IResult<T, E> {\n value: Success<T>;\n\n constructor(value: Success<T>) {\n this.value = value;\n }\n\n isOk(): this is Ok<T, E> {\n return true;\n }\n\n isErr(): this is Err<T, E> {\n return false;\n }\n}\n\n/**\n * Represents an error `Result` value.\n *\n * @template T - The type of the successful value.\n * @template E - The type of the error, must extend `BaseError`.\n */\nexport class Err<T, E extends BaseError> implements IResult<T, E> {\n error: E;\n\n constructor(error: E) {\n this.error = error;\n }\n\n isOk(): this is Ok<T, E> {\n return false;\n }\n\n isErr(): this is Err<T, E> {\n return true;\n }\n}\n\n/**\n * Creates a new successful `Result` (i.e., an instance of `Ok`).\n *\n * @template T - The type of the successful value\n * @param value - The successful value\n * @returns A new `Ok` instance.\n */\nexport function ok<const T>(value: Success<T>): Result<T, never> {\n return new Ok(value);\n}\n\n/**\n * Creates a new error `Result` (i.e., an instance of `Err`).\n *\n * @template E - The type of the error, must extend `BaseError`.\n * @param error - The error value.\n * @returns A new `Err` instance.\n */\nexport function err<const E extends BaseError>(error: E): Result<never, E> {\n return new Err(error);\n}\n","import { NextRequest } from \"next/server\";\nimport { revalidatePath } from \"next/cache\";\nimport { jwtDecode } from \"jwt-decode\";\nimport { IConfig, IRequestOptions, RouteHandler } from \"../types\";\nimport { DefaultUser, getSession } from \"./session\";\nimport { serverSideFetch, attemptTokenRefresh } from \"./fetch\";\n\nconst rHandler: RouteHandler = {\n GET: {\n user: ({ request, config }) => getUser(request, config),\n refresh: ({ request, config }) => refresh(request, config),\n logout: ({ config }) => logout(config),\n debug: () => debug(),\n oauth: ({ request, config }) => oauth(request, config),\n oauth_callback: ({ request, config }) => oauth_callback(request, config),\n proxy: ({ request, config, options }) =>\n proxyFunction(\"GET\", request, config, options),\n },\n POST: {\n login: ({ request, config }) => login(request, config),\n proxy: ({ request, config, options }) =>\n proxyFunction(\"POST\", request, config, options),\n },\n DELETE: {\n proxy: ({ request, config, options }) =>\n proxyFunction(\"DELETE\", request, config, options),\n },\n};\n\nexport async function Proxy(\n method: string,\n request: NextRequest,\n options: IRequestOptions,\n config: IConfig\n) {\n try {\n const params = await options.params;\n const parameters = {\n request,\n path:\n params.endpoint[0] ||\n request.nextUrl.pathname.replace(config.route, \"\"),\n options: params.endpoint,\n config,\n };\n\n if (config.debug) console.log(\"#> proxy:\", parameters);\n\n if (rHandler[method][parameters.path])\n return await rHandler[method][parameters.path](parameters);\n\n return Response.json({\n error: \"INVALID_ENDPOINT\",\n message: \"the provided endpoint is not valid\",\n });\n } catch (e) {\n console.log(\"#> proxyError:\", e);\n Response.json({\n error: \"REQUEST_ERROR\",\n message: \"error while sending request through frontend-backend proxy\",\n });\n }\n}\n\nasync function login(request: NextRequest, config: IConfig) {\n const formData = await request.json();\n const res = await serverSideFetch<{ token: string; refresh: string }>({\n method: \"POST\",\n url: \"/login\",\n body: formData,\n sessionIsOptional: true,\n config,\n });\n\n if (config.debug) console.log(\"#> login\", res);\n if (res.isErr()) {\n return Response.json(res.error);\n }\n\n const dec = jwtDecode<any>(res.value.data.token);\n\n const session = await getSession();\n session.token = {\n jwt: res.value.data.token,\n refresh: res.value.data.refresh || \"refresh_token\",\n decoded: dec,\n };\n\n await session.save();\n\n return Response.json({\n redirect: \"/\",\n });\n}\n\nasync function getUser(request: NextRequest, config: IConfig) {\n const session = await getSession();\n\n if (session.token === undefined)\n return Response.json({\n error: \"SESSION_ERROR\",\n message: \"Session is required but not found.\",\n });\n\n const force = request.nextUrl.searchParams.get(\"force\") === \"true\";\n\n // * User already exists in session\n if (session.user !== undefined && !force)\n return Response.json({\n data: session.user,\n });\n\n // * User does not exist in session\n const res = await serverSideFetch<DefaultUser>({\n url: `${config.userEndpoint}`,\n config,\n });\n\n if (config.debug) console.log(\"#> getUser\", res);\n if (res.isErr()) {\n return Response.json(res.error);\n }\n\n session.user = res.value.data;\n await session.save();\n\n return Response.json({\n data: session.user,\n });\n}\n\nasync function oauth(request: NextRequest, config: IConfig) {\n const authUrl = request.nextUrl.searchParams.get(\"authUrl\");\n const state = request.nextUrl.searchParams.get(\"state\");\n\n if (!authUrl) throw new Error(\"No authUrl provided\");\n\n const url = new URL(config.route + \"/oauth_callback\", config.host);\n if (state) url.searchParams.set(\"state\", state);\n\n const oAuthUrl = new URL(authUrl, config.apiUrl);\n oAuthUrl.searchParams.set(\"returnUrl\", url.toString());\n\n const res = await serverSideFetch({\n url: oAuthUrl.pathname + oAuthUrl.search,\n config,\n sessionIsOptional: true,\n });\n\n if (res.isErr()) {\n if (config.debug) console.log(\"#> oauthError\", res.error);\n return Response.json(res.error);\n }\n\n return Response.json(res.value);\n}\n\nasync function oauth_callback(request: NextRequest, config: IConfig) {\n const refresh = request.nextUrl.searchParams.get(\"refresh\");\n\n const token = request.nextUrl.searchParams.get(\"token\");\n if (token === null) throw new Error(\"No token provided\");\n\n const dec = jwtDecode<any>(token);\n\n const session = await getSession();\n session.token = {\n jwt: token,\n refresh: refresh || \"refresh_token\",\n decoded: dec,\n };\n\n await session.save();\n\n // redirect to return url if provided\n const state = request.nextUrl.searchParams.get(\"state\");\n if (state !== null)\n return Response.redirect(\n state.includes(\"http\") ? state : config.host + state\n );\n\n return Response.redirect(config.host);\n}\n\nasync function logout(config: IConfig) {\n const session = await getSession();\n session.destroy();\n\n revalidatePath(config.host, \"layout\");\n\n return Response.json({\n redirect: \"/\",\n });\n}\n\nasync function debug() {\n return Response.json(await getSession());\n}\n\nasync function refresh(request: NextRequest, config: IConfig) {\n const result = await attemptTokenRefresh(config);\n\n if (config.debug) console.log(\"#> refresh result\", result);\n\n if (result.isErr()) {\n return Response.json(result.error, { status: 401 });\n }\n\n const url = request.nextUrl;\n url.pathname = decodeURIComponent(url.searchParams.get(\"r\") || \"\");\n url.searchParams.delete(\"r\");\n\n return Response.redirect(url);\n}\n\nasync function proxyFunction(\n method: \"GET\" | \"POST\" | \"DELETE\",\n request: NextRequest,\n config: IConfig,\n options: string[]\n) {\n options.shift(); // remove the first element which is the endpoint\n const res = await serverSideFetch({\n method,\n url: `/${options.join(\"/\")}${request.nextUrl.search}`,\n body: method === \"POST\" ? await request.json() : undefined,\n config,\n });\n\n if (config.debug) console.log(\"#> proxyFunction\", res);\n if (res.isErr()) {\n return Response.json(res.error);\n }\n\n return Response.json(res.value);\n}\n","import { SessionOptions } from \"iron-session\";\nimport { getIronSession } from \"iron-session\";\nimport { cookies } from \"next/headers\";\nimport { ServerSideSession } from \"../types/internal\";\nimport { Session } from \"../types\";\n\ndeclare module \"iron-session\" {\n interface IronSessionData<U, T> {\n user?: U;\n token?: {\n jwt: string;\n refresh: string;\n decoded: T;\n };\n }\n}\n\nexport interface DefaultUser {\n [key: string]: unknown;\n}\n\nexport interface Token {\n token: string;\n}\n\nexport const sessionOptions: SessionOptions = {\n password: process.env.CELESTYA_SECRET || \"PLEASE_SET_PASSWORD\",\n cookieName: process.env.CELESTYA_COOKIE_NAME || \"PLEASE_SET_COOKIE_NAME\",\n cookieOptions: { secure: process.env.SECURE === \"true\" },\n};\n\nexport const getSession = async <U = DefaultUser>(\n sessionOpts?: SessionOptions\n) => {\n if (\n sessionOpts === undefined &&\n (!process.env.CELESTYA_SECRET || !process.env.CELESTYA_COOKIE_NAME)\n ) {\n throw new Error(\n \"CELESTYA_SECRET and CELESTYA_COOKIE_NAME must be set in environment variables.\"\n );\n }\n\n const session: Session<U> = await getIronSession<ServerSideSession<U>>(\n await cookies(),\n sessionOpts || sessionOptions\n );\n\n return session;\n};\n","import { IConfig } from \"../types\";\nimport { BaseError, err, ok, Result, Success } from \"../types/response\";\nimport { getSession } from \"./session\";\n\n// Global refresh lock to prevent multiple simultaneous refresh attempts\nlet refreshPromise: Promise<Result<string, BaseError>> | null = null;\n\nexport const serverSideFetch = async <T>({\n url,\n method = \"GET\",\n config,\n body,\n sessionIsOptional = false,\n skipRefresh = false,\n ...options\n}: {\n url: string;\n method?: \"GET\" | \"POST\" | \"DELETE\";\n body?: object;\n config: IConfig;\n sessionIsOptional?: boolean;\n skipRefresh?: boolean;\n} & Omit<RequestInit, \"body\" | \"method\">): Promise<Result<T, BaseError>> => {\n const headers = new Headers({\n \"Content-Type\": \"application/json\",\n ...options.headers,\n });\n\n const session = await getSession();\n\n if (session.token !== undefined) {\n headers.set(\"Authorization\", `Bearer ${session.token.jwt}`);\n } else if (!sessionIsOptional) {\n return err({\n error: \"SESSION_ERROR\",\n message: \"Session is required but not found.\",\n });\n }\n\n const opts: RequestInit = {\n method,\n headers,\n ...options,\n };\n\n try {\n if (body) opts.body = JSON.stringify(body);\n } catch (e) {\n console.log(\"Error stringifying body: \", e);\n }\n\n try {\n const response: Response = await fetch(`${config.apiUrl}${url}`, opts);\n\n // Handle 401 Unauthorized - try to refresh token\n if (response.status === 401 && !skipRefresh && !sessionIsOptional) {\n if (config.debug)\n console.log(\"#> 401 detected, attempting token refresh\");\n\n // Local reference to the refresh promise to prevent race conditions\n let currentRefresh: Promise<Result<string, BaseError>>;\n\n // Check if refresh is already in progress\n if (refreshPromise === null) {\n // Start new refresh process\n refreshPromise = attemptTokenRefresh(config).finally(() => {\n // Clear the lock when done (success or failure)\n refreshPromise = null;\n });\n currentRefresh = refreshPromise;\n } else {\n if (config.debug)\n console.log(\"#> Refresh already in progress, waiting...\");\n currentRefresh = refreshPromise;\n }\n\n // Wait for the refresh to complete (whether we started it or not)\n const refreshResult = await currentRefresh;\n\n if (refreshResult.isOk()) {\n // Retry the original request with refreshed token\n return serverSideFetch<T>({\n url,\n method,\n config,\n body,\n sessionIsOptional,\n skipRefresh: true, // Prevent infinite loop\n ...options,\n });\n }\n\n // Refresh failed, return the error\n return err(refreshResult.error);\n }\n\n if (!response.ok) {\n return err({\n error: \"RESPONSE_ERROR\",\n message: `HTTP error! status: ${response.status}`,\n });\n }\n\n try {\n const res = await response.json();\n if (res.error !== undefined) {\n return err(res);\n }\n\n return ok(res as Success<T>);\n } catch (e) {\n return err({\n error: \"PARSE_ERROR\",\n message: \"Failed to parse response as JSON\",\n });\n }\n } catch (e) {\n return err({\n error: \"FETCH_ERROR\",\n message: \"Failed to fetch the resource: \" + String(e),\n });\n }\n};\n\nexport async function attemptTokenRefresh(\n config: IConfig\n): Promise<Result<string, BaseError>> {\n if (config.debug) console.log(\"#> attemptTokenRefresh called\");\n\n const { jwtDecode } = await import(\"jwt-decode\");\n const session = await getSession();\n\n if (!session.token?.refresh) {\n return err({\n error: \"NO_REFRESH_TOKEN\",\n message: \"No refresh token available in session\",\n });\n }\n\n const res = await serverSideFetch<{ token: string }>({\n method: \"POST\",\n url: \"/refresh\",\n body: {\n refreshToken: session.token.refresh,\n },\n sessionIsOptional: true,\n skipRefresh: true, // Prevent infinite loop\n config,\n });\n\n if (config.debug) console.log(\"#> attemptTokenRefresh\", res);\n if (res.isErr()) {\n // Refresh token is invalid or expired, destroy session\n session.destroy();\n return err(res.error);\n }\n\n // Update session with new JWT\n const decoded = jwtDecode<any>(res.value.data.token);\n const newToken = {\n jwt: res.value.data.token,\n refresh: session.token.refresh, // Keep the same refresh token\n decoded,\n };\n\n session.token = newToken;\n\n await session.save();\n\n return ok({ data: \"success\" });\n}\n","import { NextRequest } from \"next/server\";\nimport { IConfig, IRequestOptions } from \"../types\";\nimport { Proxy } from \"./api\";\n\nexport const CelestyaProxy = (config: IConfig) => {\n return {\n POST: (req: NextRequest, opt: IRequestOptions) =>\n Proxy(\"POST\", req, opt, config),\n GET: (req: NextRequest, opt: IRequestOptions) =>\n Proxy(\"GET\", req, opt, config),\n DELETE: (req: NextRequest, opt: IRequestOptions) =>\n Proxy(\"DELETE\", req, opt, config),\n };\n};\n","import { CallbackOptions, IConfig, WrapperFunction } from \"../types\";\nimport { serverSideFetch } from \"./fetch\";\n\n/**\n * Register new Wrapper for the API.\n *\n * Example Wrapper:\n * ```ts\n * const apiWrapper = (cb: WrapperFunction) => {\n * return {\n * commmands: {\n * get: () => cb<string>({ method: \"GET\", url: \"/command\" }),\n * update: (id: string, body: JSON) =>\n * cb({ method: \"POST\", url: `/command/${id}`, body }),\n * },\n * };\n * };\n * ````\n * @param apiWrapper\n * @param config\n * @returns\n */\nexport const serverAPIWrapper = <T>(\n apiWrapper: (cb: WrapperFunction) => T,\n config: IConfig\n) => {\n return apiWrapper(async (data: CallbackOptions) => {\n const { method, url, body } = data;\n\n return serverSideFetch({\n url,\n method,\n body,\n config,\n });\n });\n};\n"],"mappings":"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","names":["jwtDecode","Proxy","refresh","Proxy"]}