hapta 1.0.1 → 1.0.2

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.
@@ -80,7 +80,7 @@ type TokenOptions = {
80
80
  iat: number
81
81
  }
82
82
  type VerifyFn = (token: string) => Promise<Principal>;
83
-
83
+ type TempTokenFn = (amount_of_uses: number, expiresAt: '1h' | '1d' | '1y'|'') => Promise<string | null>
84
84
  export type ServiceConfigs = {
85
85
  Clover: {
86
86
  Tenant_ID: string;
@@ -88,7 +88,8 @@ export type ServiceConfigs = {
88
88
  Authorized_Users: string[];
89
89
  Authenticate: AuthenticateFn;
90
90
  Register: RegisterFn;
91
- Verify?: VerifyFn; // just verify token
91
+ Verify?: VerifyFn;
92
+ createTemporaryToken: TempTokenFn // just verify token
92
93
  };
93
94
  };
94
95
 
package/index.ts CHANGED
@@ -13,7 +13,7 @@ import * as z from "zod";
13
13
  import { watch } from "fs";
14
14
  import fs from "fs"
15
15
  import { pathToFileURL } from "url";
16
-
16
+ const token_uses = new Map<string, number>()
17
17
  // --- Global server and router instances ---
18
18
  let server: Server;
19
19
  // MODIFIED: Make the router a single, persistent instance
@@ -103,7 +103,8 @@ async function createServeConfig(): Promise<Serve> {
103
103
 
104
104
  return {
105
105
  port: config.port,
106
- async fetch(req: Request) {
106
+ async fetch(req: Request) {
107
+ console.log(req.method)
107
108
  if (req.method === "OPTIONS") {
108
109
  console.log("ran")
109
110
  return new Response(null, {
@@ -115,7 +116,8 @@ async function createServeConfig(): Promise<Serve> {
115
116
  "Access-Control-Max-Age": "86400",
116
117
  },
117
118
  });
118
- }
119
+ }
120
+ console.log("ran")
119
121
  const url = new URL(req.url);
120
122
  const routeMatch = router.match(url.href);
121
123
 
@@ -218,17 +220,18 @@ async function buildRequestContext(req: Request, headers: Headers) {
218
220
  const reqJSON = await req.json().catch(() => ({}));
219
221
 
220
222
  const hasToken = headers.has("Authorization")
221
- var isAuthenticated = false;
223
+ var isAuthenticated = false;
222
224
  if (hasToken) {
225
+
223
226
  try {
224
- jwt.verify(token as string, config.JWT_SECRET)
227
+
225
228
  isAuthenticated = true
226
229
  } catch (error) {
227
230
  isAuthenticated = false
228
231
  }
229
232
  }
230
- const context = {
231
- principal: { isAuthenticated },
233
+ const context = {
234
+ principal: { isAuthenticated: isAuthenticated as boolean },
232
235
  services: {
233
236
  Clover: {
234
237
  Tenant_ID: primaryTenantData.id,
@@ -274,7 +277,7 @@ async function buildRequestContext(req: Request, headers: Headers) {
274
277
  }
275
278
 
276
279
 
277
- const authRes = await fetch(`${config.Clover_Server_Url}/oauth/token`, {
280
+ const authRes = await fetch(`${config.Clover_Server_Url}/${options.type === "oauth" ? 'oauth/token' :'auth'}`, {
278
281
  method: "POST",
279
282
  headers: {
280
283
  "Content-Type": "application/json",
@@ -285,7 +288,7 @@ async function buildRequestContext(req: Request, headers: Headers) {
285
288
  body: JSON.stringify(fetchBody),
286
289
  });
287
290
 
288
- if (!authRes.ok) {
291
+ if (!authRes.ok) {
289
292
  return {
290
293
  isAuthenticated: false,
291
294
  error: true,
@@ -314,18 +317,29 @@ async function buildRequestContext(req: Request, headers: Headers) {
314
317
  Verify: async (token) => {
315
318
  try {
316
319
  const payload = jwt.verify(token, config.JWT_SECRET);
320
+ if(token_uses.has(token) && token_uses.get(token) >= payload.amount_of_uses){
321
+ // this is basic auth token
322
+ throw new Error("token has been used wayy to many times, it is expired")
323
+ }else{
324
+ token_uses.set(token, Number(token_uses.get(token)) + 1)
325
+ }
317
326
  return {
318
- isAuthenticated: true,
319
- id: payload.id,
320
- clover_group_assigned_To: payload.Group,
321
- clover_assigned_id: payload.clover_assigned_id,
322
- Roles: payload.Roles,
327
+ isAuthenticated: true,
328
+ id: payload.id || crypto.randomUUID(),
329
+ clover_group_assigned_To: payload.Group || [],
330
+ clover_assigned_id: payload.clover_assigned_id || primaryTenantData.id,
331
+ Roles: payload.Roles || [],
323
332
  token,
324
333
  };
325
334
  } catch {
326
335
  return { isAuthenticated: false };
327
336
  }
328
337
  },
338
+ createTemporaryToken(amount_of_uses: number, expiresAt: string) {
339
+ const token = jwt.sign({amount_of_uses, isBasicAuth: true, security_level: 0}, config.JWT_SECRET, { expiresIn: expiresAt })
340
+ token_uses.set(token, 0)
341
+ return token
342
+ },
329
343
  Roles: Array.isArray(primaryTenantData.Tenant_Roles)
330
344
  ? primaryTenantData.Tenant_Roles
331
345
  : [primaryTenantData.Tenant_Roles],
@@ -362,13 +376,26 @@ async function buildRequestContext(req: Request, headers: Headers) {
362
376
  "Access-Control-Allow-Headers": "Content-Type, Authorization"
363
377
  }
364
378
  })
379
+ },
380
+ text: (value: string, status?:number, statusText?: string) => {
381
+ return new Response(value, {
382
+ ...(status && {status}),
383
+ ...(statusText && {statusText}),
384
+ headers:{
385
+ "Content-Type": "text/html",
386
+ "Access-Control-Allow-Origin": config.origin,
387
+ "Access-Control-Allow-Methods": "GET,PATCH,PUT,DELETE",
388
+ "Access-Control-Allow-Headers": "Content-Type, Authorization"
389
+ }
390
+ })
365
391
  }
366
392
  };
367
393
 
368
394
  const authHeader = headers.get("authorization");
369
395
  const token = authHeader?.startsWith("Bearer ") ? authHeader.split(" ")[1] : authHeader;
396
+
370
397
 
371
- if (token) {
398
+ if (token) {
372
399
  context.principal = await context.services.Clover.Verify(token);
373
400
  }
374
401
 
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "bin": {
4
4
  "hapta":"./index.ts"
5
5
  },
6
- "version": "1.0.1",
6
+ "version": "1.0.2",
7
7
  "description": "modular, scalable, and feature-rich backend framework designed to extend Pocketbase with authentication, schema validation, caching, and tenant-based service orchestration.",
8
8
  "dependencies": {
9
9
  "jsonwebtoken": "^9.0.2",