@shware/security 7.1.1 → 8.0.1

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.
Files changed (132) hide show
  1. package/README.md +113 -32
  2. package/dist/auth/attributes.cjs +4 -3
  3. package/dist/auth/attributes.cjs.map +1 -1
  4. package/dist/auth/attributes.d.cts +3 -3
  5. package/dist/auth/attributes.d.cts.map +1 -1
  6. package/dist/auth/attributes.d.mts +3 -3
  7. package/dist/auth/attributes.d.mts.map +1 -1
  8. package/dist/auth/attributes.mjs +4 -3
  9. package/dist/auth/attributes.mjs.map +1 -1
  10. package/dist/auth/desktop-codes.cjs +57 -0
  11. package/dist/auth/desktop-codes.cjs.map +1 -0
  12. package/dist/auth/desktop-codes.d.cts +24 -0
  13. package/dist/auth/desktop-codes.d.cts.map +1 -0
  14. package/dist/auth/desktop-codes.d.mts +24 -0
  15. package/dist/auth/desktop-codes.d.mts.map +1 -0
  16. package/dist/auth/desktop-codes.mjs +55 -0
  17. package/dist/auth/desktop-codes.mjs.map +1 -0
  18. package/dist/auth/email-codes.cjs +77 -0
  19. package/dist/auth/email-codes.cjs.map +1 -0
  20. package/dist/auth/email-codes.d.cts +39 -0
  21. package/dist/auth/email-codes.d.cts.map +1 -0
  22. package/dist/auth/email-codes.d.mts +39 -0
  23. package/dist/auth/email-codes.d.mts.map +1 -0
  24. package/dist/auth/email-codes.mjs +75 -0
  25. package/dist/auth/email-codes.mjs.map +1 -0
  26. package/dist/auth/error.cjs +47 -0
  27. package/dist/auth/error.cjs.map +1 -0
  28. package/dist/auth/error.d.cts +88 -0
  29. package/dist/auth/error.d.cts.map +1 -0
  30. package/dist/auth/error.d.mts +88 -0
  31. package/dist/auth/error.d.mts.map +1 -0
  32. package/dist/auth/error.mjs +45 -0
  33. package/dist/auth/error.mjs.map +1 -0
  34. package/dist/auth/index.cjs +249 -384
  35. package/dist/auth/index.cjs.map +1 -1
  36. package/dist/auth/index.d.cts +66 -55
  37. package/dist/auth/index.d.cts.map +1 -1
  38. package/dist/auth/index.d.mts +66 -55
  39. package/dist/auth/index.d.mts.map +1 -1
  40. package/dist/auth/index.mjs +252 -387
  41. package/dist/auth/index.mjs.map +1 -1
  42. package/dist/auth/respond.cjs +99 -0
  43. package/dist/auth/respond.cjs.map +1 -0
  44. package/dist/auth/respond.d.cts +39 -0
  45. package/dist/auth/respond.d.cts.map +1 -0
  46. package/dist/auth/respond.d.mts +39 -0
  47. package/dist/auth/respond.d.mts.map +1 -0
  48. package/dist/auth/respond.mjs +92 -0
  49. package/dist/auth/respond.mjs.map +1 -0
  50. package/dist/auth/types.d.cts +27 -11
  51. package/dist/auth/types.d.cts.map +1 -1
  52. package/dist/auth/types.d.mts +27 -11
  53. package/dist/auth/types.d.mts.map +1 -1
  54. package/dist/index.cjs +5 -0
  55. package/dist/index.d.cts +4 -1
  56. package/dist/index.d.mts +4 -1
  57. package/dist/index.mjs +3 -1
  58. package/dist/oauth2/error.cjs +0 -7
  59. package/dist/oauth2/error.cjs.map +1 -1
  60. package/dist/oauth2/error.d.cts +0 -3
  61. package/dist/oauth2/error.d.cts.map +1 -1
  62. package/dist/oauth2/error.d.mts +0 -3
  63. package/dist/oauth2/error.d.mts.map +1 -1
  64. package/dist/oauth2/error.mjs +1 -7
  65. package/dist/oauth2/error.mjs.map +1 -1
  66. package/dist/oauth2/provider/common.cjs +17 -3
  67. package/dist/oauth2/provider/common.cjs.map +1 -1
  68. package/dist/oauth2/provider/common.d.cts.map +1 -1
  69. package/dist/oauth2/provider/common.d.mts.map +1 -1
  70. package/dist/oauth2/provider/common.mjs +17 -3
  71. package/dist/oauth2/provider/common.mjs.map +1 -1
  72. package/dist/oauth2/provider/facebook.cjs +2 -4
  73. package/dist/oauth2/provider/facebook.cjs.map +1 -1
  74. package/dist/oauth2/provider/facebook.d.cts +0 -1
  75. package/dist/oauth2/provider/facebook.d.cts.map +1 -1
  76. package/dist/oauth2/provider/facebook.d.mts +0 -1
  77. package/dist/oauth2/provider/facebook.d.mts.map +1 -1
  78. package/dist/oauth2/provider/facebook.mjs +2 -4
  79. package/dist/oauth2/provider/facebook.mjs.map +1 -1
  80. package/dist/oauth2/provider/github.cjs +1 -1
  81. package/dist/oauth2/provider/github.cjs.map +1 -1
  82. package/dist/oauth2/provider/github.d.cts +1 -1
  83. package/dist/oauth2/provider/github.d.cts.map +1 -1
  84. package/dist/oauth2/provider/github.d.mts +1 -1
  85. package/dist/oauth2/provider/github.d.mts.map +1 -1
  86. package/dist/oauth2/provider/github.mjs +1 -1
  87. package/dist/oauth2/provider/github.mjs.map +1 -1
  88. package/dist/oauth2/provider/x.cjs +6 -4
  89. package/dist/oauth2/provider/x.cjs.map +1 -1
  90. package/dist/oauth2/provider/x.d.cts +3 -2
  91. package/dist/oauth2/provider/x.d.cts.map +1 -1
  92. package/dist/oauth2/provider/x.d.mts +3 -2
  93. package/dist/oauth2/provider/x.d.mts.map +1 -1
  94. package/dist/oauth2/provider/x.mjs +6 -4
  95. package/dist/oauth2/provider/x.mjs.map +1 -1
  96. package/dist/oauth2/types.cjs.map +1 -1
  97. package/dist/oauth2/types.d.cts +5 -0
  98. package/dist/oauth2/types.d.cts.map +1 -1
  99. package/dist/oauth2/types.d.mts +5 -0
  100. package/dist/oauth2/types.d.mts.map +1 -1
  101. package/dist/oauth2/types.mjs.map +1 -1
  102. package/dist/session/common.cjs +10 -13
  103. package/dist/session/common.cjs.map +1 -1
  104. package/dist/session/common.d.cts +7 -3
  105. package/dist/session/common.d.cts.map +1 -1
  106. package/dist/session/common.d.mts +7 -3
  107. package/dist/session/common.d.mts.map +1 -1
  108. package/dist/session/common.mjs +10 -12
  109. package/dist/session/common.mjs.map +1 -1
  110. package/dist/session/db.cjs +2 -2
  111. package/dist/session/db.cjs.map +1 -1
  112. package/dist/session/db.mjs +3 -3
  113. package/dist/session/db.mjs.map +1 -1
  114. package/dist/session/redis.cjs +6 -8
  115. package/dist/session/redis.cjs.map +1 -1
  116. package/dist/session/redis.d.cts.map +1 -1
  117. package/dist/session/redis.d.mts.map +1 -1
  118. package/dist/session/redis.mjs +7 -9
  119. package/dist/session/redis.mjs.map +1 -1
  120. package/dist/session/types.d.cts +0 -12
  121. package/dist/session/types.d.cts.map +1 -1
  122. package/dist/session/types.d.mts +0 -12
  123. package/dist/session/types.d.mts.map +1 -1
  124. package/dist/utils/valid.cjs +34 -52
  125. package/dist/utils/valid.cjs.map +1 -1
  126. package/dist/utils/valid.d.cts +8 -23
  127. package/dist/utils/valid.d.cts.map +1 -1
  128. package/dist/utils/valid.d.mts +8 -23
  129. package/dist/utils/valid.d.mts.map +1 -1
  130. package/dist/utils/valid.mjs +32 -50
  131. package/dist/utils/valid.mjs.map +1 -1
  132. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/session/types.ts"],"mappings":";iBAEiB,uBAAuB;EACtC;EACA,YAAY;EACZ;EACA;EACA;;iBAGe;EACf;EACA,iBAAiB;;YAGP;iBAGK;EACf;EACA;EAEA,aAAa;EACb;EACA,aAAa,cAAc;EAC3B,gBAAgB;EAEhB;EACA;EACA,oBAAoB;EAEpB;EACA,uBAAuB;EAEvB;;iBAGe,kBAAkB,UAAU,UAAU;EACrD,iBAAiB;EACjB,KAAK,SAAS,IAAI;EAClB,SAAS,oBAAoB,QAAQ;EACrC,WAAW,oBAAoB;EAG/B,6BAA6B,mBAAmB,qBAAqB,QAAQ,YAAY;EACzF,oBAAoB,wBAAwB,QAAQ,YAAY;EAGhE,uBAAuB,wBAAwB;;;;;;iBAOhC;EACf,QAAQ,aAAa,eAAe,qBAAqB;EACzD,QAAQ,cAAc;EACtB,WAAW,cAAc;;;;;;;EAOzB,UAAU,aAAa,oBAAoB"}
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../../src/session/types.ts"],"mappings":"A,YAEY;iBAEK;EACf;EACA;EAEA,aAAa;EACb;EACA,aAAa,cAAc;EAC3B,gBAAgB;EAEhB;EACA;EACA,oBAAoB;EAEpB;EACA,uBAAuB;EAEvB;;iBAGe,kBAAkB,UAAU,UAAU;EACrD,iBAAiB;EACjB,KAAK,SAAS,IAAI;EAClB,SAAS,oBAAoB,QAAQ;EACrC,WAAW,oBAAoB;EAG/B,6BAA6B,mBAAmB,qBAAqB,QAAQ,YAAY;EACzF,oBAAoB,wBAAwB,QAAQ,YAAY;EAGhE,uBAAuB,wBAAwB;;;;;;iBAOhC;EACf,QAAQ,aAAa,eAAe,qBAAqB;EACzD,QAAQ,cAAc;EACtB,WAAW,cAAc;;;;;;;EAOzB,UAAU,aAAa,oBAAoB"}
@@ -1,68 +1,50 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_auth_respond = require("../auth/respond.cjs");
2
3
  // src/utils/valid.ts
3
- function invalidArgument(reason) {
4
- return { error: {
5
- code: 400,
6
- status: "INVALID_ARGUMENT",
7
- message: "Invalid verification code",
8
- details: [{
9
- "@type": "type.googleapis.com/google.rpc.ErrorInfo",
10
- reason
11
- }]
12
- } };
4
+ /** The body as JSON, or a 400 for one that is not JSON. */
5
+ async function readJson(request) {
6
+ try {
7
+ return await request.json();
8
+ } catch {
9
+ throw require_auth_respond.invalidArgument("INVALID_JSON", "Request body is not valid JSON");
10
+ }
13
11
  }
14
- function resourceExhausted(reason, message) {
15
- return { error: {
16
- code: 429,
17
- status: "RESOURCE_EXHAUSTED",
18
- message,
19
- details: [{
20
- "@type": "type.googleapis.com/google.rpc.ErrorInfo",
21
- reason
22
- }]
23
- } };
12
+ /** The body as a form, or a 400 for one that is not `application/x-www-form-urlencoded`. */
13
+ async function readForm(request) {
14
+ if (!(request.headers.get("content-type")?.toLowerCase() ?? "").startsWith("application/x-www-form-urlencoded")) throw require_auth_respond.invalidArgument("INVALID_CONTENT_TYPE", "Expected application/x-www-form-urlencoded");
15
+ return Object.fromEntries(new URLSearchParams(await request.text()));
24
16
  }
25
- function valid(schema, json) {
26
- const result = schema.safeParse(json);
27
- if (result.success) return {
28
- error: null,
29
- data: result.data
30
- };
31
- return {
32
- error: { error: {
33
- code: 400,
34
- status: "INVALID_ARGUMENT",
35
- message: "Invalid request",
36
- details: [{
37
- "@type": "type.googleapis.com/google.rpc.BadRequest",
38
- fieldViolations: result.error.issues.map(({ code, path, message }) => ({
39
- field: path.join("."),
40
- description: message,
41
- reason: code.toUpperCase(),
42
- localizedMessage: {
43
- locale: "en-US",
44
- message
45
- }
46
- }))
47
- }]
48
- } },
49
- data: null
50
- };
17
+ /** `value` as `schema` reads it, or a 400 `BadRequest` naming each field that failed. */
18
+ function parse(schema, value) {
19
+ const result = schema.safeParse(value);
20
+ if (result.success) return result.data;
21
+ const fieldViolations = result.error.issues.map(({ code, path, message }) => ({
22
+ field: path.join("."),
23
+ description: message,
24
+ reason: code.toUpperCase(),
25
+ localizedMessage: {
26
+ locale: "en-US",
27
+ message
28
+ }
29
+ }));
30
+ throw require_auth_respond.invalidArgument("INVALID_ARGUMENT", "Invalid request", [{
31
+ "@type": "type.googleapis.com/google.rpc.BadRequest",
32
+ fieldViolations
33
+ }]);
51
34
  }
52
35
  async function verifyTurnstileToken(secret, token) {
53
- if ((await (await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
36
+ if (!(await (await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
54
37
  method: "POST",
55
38
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
56
39
  body: new URLSearchParams({
57
40
  secret,
58
41
  response: token
59
42
  })
60
- })).json()).success) return { error: null };
61
- return { error: invalidArgument("TURNSTILE_VERIFICATION_FAILED") };
43
+ })).json()).success) throw require_auth_respond.invalidArgument("TURNSTILE_VERIFICATION_FAILED", "Turnstile verification failed");
62
44
  }
63
- exports.invalidArgument = invalidArgument;
64
- exports.resourceExhausted = resourceExhausted;
65
- exports.valid = valid;
45
+ exports.parse = parse;
46
+ exports.readForm = readForm;
47
+ exports.readJson = readJson;
66
48
  exports.verifyTurnstileToken = verifyTurnstileToken;
67
49
 
68
50
  //# sourceMappingURL=valid.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"valid.cjs","names":[],"sources":["../../src/utils/valid.ts"],"sourcesContent":["import type { ZodType, output } from 'zod';\nimport type { ZodMiniType, output as outputMini } from 'zod/mini';\n\ntype ErrorBody = {\n error: {\n code: number;\n status: string;\n message: string;\n details: unknown[];\n };\n};\n\nexport function invalidArgument(reason: string): ErrorBody {\n return {\n error: {\n code: 400,\n status: 'INVALID_ARGUMENT',\n message: 'Invalid verification code',\n details: [{ '@type': 'type.googleapis.com/google.rpc.ErrorInfo', reason }],\n },\n };\n}\n\nexport function resourceExhausted(reason: string, message: string): ErrorBody {\n return {\n error: {\n code: 429,\n status: 'RESOURCE_EXHAUSTED',\n message,\n details: [{ '@type': 'type.googleapis.com/google.rpc.ErrorInfo', reason }],\n },\n };\n}\n\ntype Result<S extends ZodType | ZodMiniType> =\n | { error: null; data: S extends ZodType ? output<S> : outputMini<S> }\n | { error: ErrorBody; data: null };\n\nexport function valid<S extends ZodType | ZodMiniType>(schema: S, json: unknown): Result<S> {\n const result = schema.safeParse(json);\n if (result.success) {\n return {\n error: null,\n data: result.data as S extends ZodType ? output<S> : outputMini<S>,\n };\n }\n\n const fieldViolations = result.error.issues.map(({ code, path, message }) => ({\n field: path.join('.'),\n description: message,\n reason: code.toUpperCase(),\n localizedMessage: { locale: 'en-US', message },\n }));\n\n const error = {\n error: {\n code: 400,\n status: 'INVALID_ARGUMENT',\n message: 'Invalid request',\n details: [{ '@type': 'type.googleapis.com/google.rpc.BadRequest', fieldViolations }],\n },\n };\n\n return { error, data: null };\n}\n\nexport async function verifyTurnstileToken(secret: string, token: string) {\n const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({ secret, response: token }),\n });\n\n const data = (await response.json()) as { success: boolean };\n if (data.success) return { error: null };\n return { error: invalidArgument('TURNSTILE_VERIFICATION_FAILED') };\n}\n"],"mappings":";;AAYA,SAAgB,gBAAgB,QAA2B;CACzD,OAAO,EACL,OAAO;EACL,MAAM;EACN,QAAQ;EACR,SAAS;EACT,SAAS,CAAC;GAAE,SAAS;GAA4C;EAAO,CAAC;CAC3E,EACF;AACF;AAEA,SAAgB,kBAAkB,QAAgB,SAA4B;CAC5E,OAAO,EACL,OAAO;EACL,MAAM;EACN,QAAQ;EACR;EACA,SAAS,CAAC;GAAE,SAAS;GAA4C;EAAO,CAAC;CAC3E,EACF;AACF;AAMA,SAAgB,MAAuC,QAAW,MAA0B;CAC1F,MAAM,SAAS,OAAO,UAAU,IAAI;CACpC,IAAI,OAAO,SACT,OAAO;EACL,OAAO;EACP,MAAM,OAAO;CACf;CAmBF,OAAO;EAAE,OAAA,EARP,OAAO;GACL,MAAM;GACN,QAAQ;GACR,SAAS;GACT,SAAS,CAAC;IAAE,SAAS;IAA6C,iBAZ9C,OAAO,MAAM,OAAO,KAAK,EAAE,MAAM,MAAM,eAAe;KAC5E,OAAO,KAAK,KAAK,GAAG;KACpB,aAAa;KACb,QAAQ,KAAK,YAAY;KACzB,kBAAkB;MAAE,QAAQ;MAAS;KAAQ;IAC/C,EAOoF;GAAE,CAAC;EACrF,EAGW;EAAG,MAAM;CAAK;AAC7B;AAEA,eAAsB,qBAAqB,QAAgB,OAAe;CAQxE,KAAI,OADgB,MANG,MAAM,6DAA6D;EACxF,QAAQ;EACR,SAAS,EAAE,gBAAgB,oCAAoC;EAC/D,MAAM,IAAI,gBAAgB;GAAE;GAAQ,UAAU;EAAM,CAAC;CACvD,CAAC,EAAA,CAE4B,KAAK,EAAA,CACzB,SAAS,OAAO,EAAE,OAAO,KAAK;CACvC,OAAO,EAAE,OAAO,gBAAgB,+BAA+B,EAAE;AACnE"}
1
+ {"version":3,"file":"valid.cjs","names":["invalidArgument"],"sources":["../../src/utils/valid.ts"],"sourcesContent":["import type { ZodType, output } from 'zod';\nimport type { ZodMiniType, output as outputMini } from 'zod/mini';\nimport { invalidArgument } from '../auth/respond';\n\ntype Output<S extends ZodType | ZodMiniType> = S extends ZodType ? output<S> : outputMini<S>;\n\n/** The body as JSON, or a 400 for one that is not JSON. */\nexport async function readJson(request: Request): Promise<unknown> {\n try {\n return await request.json();\n } catch {\n throw invalidArgument('INVALID_JSON', 'Request body is not valid JSON');\n }\n}\n\n/** The body as a form, or a 400 for one that is not `application/x-www-form-urlencoded`. */\nexport async function readForm(request: Request): Promise<Record<string, string>> {\n const type = request.headers.get('content-type')?.toLowerCase() ?? '';\n if (!type.startsWith('application/x-www-form-urlencoded')) {\n throw invalidArgument('INVALID_CONTENT_TYPE', 'Expected application/x-www-form-urlencoded');\n }\n return Object.fromEntries(new URLSearchParams(await request.text()));\n}\n\n/** `value` as `schema` reads it, or a 400 `BadRequest` naming each field that failed. */\nexport function parse<S extends ZodType | ZodMiniType>(schema: S, value: unknown): Output<S> {\n const result = schema.safeParse(value);\n if (result.success) return result.data as Output<S>;\n const fieldViolations = result.error.issues.map(({ code, path, message }) => ({\n field: path.join('.'),\n description: message,\n reason: code.toUpperCase(),\n localizedMessage: { locale: 'en-US', message },\n }));\n throw invalidArgument('INVALID_ARGUMENT', 'Invalid request', [\n { '@type': 'type.googleapis.com/google.rpc.BadRequest', fieldViolations },\n ]);\n}\n\nexport async function verifyTurnstileToken(secret: string, token: string): Promise<void> {\n const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({ secret, response: token }),\n });\n const data = (await response.json()) as { success: boolean };\n if (!data.success) {\n throw invalidArgument('TURNSTILE_VERIFICATION_FAILED', 'Turnstile verification failed');\n }\n}\n"],"mappings":";;;;AAOA,eAAsB,SAAS,SAAoC;CACjE,IAAI;EACF,OAAO,MAAM,QAAQ,KAAK;CAC5B,QAAQ;EACN,MAAMA,qBAAAA,gBAAgB,gBAAgB,gCAAgC;CACxE;AACF;;AAGA,eAAsB,SAAS,SAAmD;CAEhF,IAAI,EADS,QAAQ,QAAQ,IAAI,cAAc,CAAC,EAAE,YAAY,KAAK,GAAA,CACzD,WAAW,mCAAmC,GACtD,MAAMA,qBAAAA,gBAAgB,wBAAwB,4CAA4C;CAE5F,OAAO,OAAO,YAAY,IAAI,gBAAgB,MAAM,QAAQ,KAAK,CAAC,CAAC;AACrE;;AAGA,SAAgB,MAAuC,QAAW,OAA2B;CAC3F,MAAM,SAAS,OAAO,UAAU,KAAK;CACrC,IAAI,OAAO,SAAS,OAAO,OAAO;CAClC,MAAM,kBAAkB,OAAO,MAAM,OAAO,KAAK,EAAE,MAAM,MAAM,eAAe;EAC5E,OAAO,KAAK,KAAK,GAAG;EACpB,aAAa;EACb,QAAQ,KAAK,YAAY;EACzB,kBAAkB;GAAE,QAAQ;GAAS;EAAQ;CAC/C,EAAE;CACF,MAAMA,qBAAAA,gBAAgB,oBAAoB,mBAAmB,CAC3D;EAAE,SAAS;EAA6C;CAAgB,CAC1E,CAAC;AACH;AAEA,eAAsB,qBAAqB,QAAgB,OAA8B;CAOvF,IAAI,EAAC,OADe,MALG,MAAM,6DAA6D;EACxF,QAAQ;EACR,SAAS,EAAE,gBAAgB,oCAAoC;EAC/D,MAAM,IAAI,gBAAgB;GAAE;GAAQ,UAAU;EAAM,CAAC;CACvD,CAAC,EAAA,CAC4B,KAAK,EAAA,CACxB,SACR,MAAMA,qBAAAA,gBAAgB,iCAAiC,+BAA+B;AAE1F"}
@@ -1,27 +1,12 @@
1
1
  import { ZodType, output } from "zod";
2
2
  import { ZodMiniType, output as output$1 } from "zod/mini";
3
- type ErrorBody = {
4
- error: {
5
- code: number;
6
- status: string;
7
- message: string;
8
- details: unknown[];
9
- };
10
- };
11
- export declare function invalidArgument(reason: string): ErrorBody;
12
- export declare function resourceExhausted(reason: string, message: string): ErrorBody;
13
- type Result<S extends ZodType | ZodMiniType> = {
14
- error: null;
15
- data: S extends ZodType ? output<S> : output$1<S>;
16
- } | {
17
- error: ErrorBody;
18
- data: null;
19
- };
20
- export declare function valid<S extends ZodType | ZodMiniType>(schema: S, json: unknown): Result<S>;
21
- export declare function verifyTurnstileToken(secret: string, token: string): Promise<{
22
- error: null;
23
- } | {
24
- error: ErrorBody;
25
- }>;
3
+ type Output<S extends ZodType | ZodMiniType> = S extends ZodType ? output<S> : output$1<S>;
4
+ /** The body as JSON, or a 400 for one that is not JSON. */
5
+ export declare function readJson(request: Request): Promise<unknown>;
6
+ /** The body as a form, or a 400 for one that is not `application/x-www-form-urlencoded`. */
7
+ export declare function readForm(request: Request): Promise<Record<string, string>>;
8
+ /** `value` as `schema` reads it, or a 400 `BadRequest` naming each field that failed. */
9
+ export declare function parse<S extends ZodType | ZodMiniType>(schema: S, value: unknown): Output<S>;
10
+ export declare function verifyTurnstileToken(secret: string, token: string): Promise<void>;
26
11
  export {};
27
12
  //# sourceMappingURL=valid.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"valid.d.cts","names":["outputMini"],"sources":["../../src/utils/valid.ts"],"mappings":";;KAGK;EACH;IACE;IACA;IACA;IACA;;;wBAIY,gBAAgB,iBAAiB;wBAWjC,kBAAkB,gBAAgB,kBAAkB;KAW/D,OAAO,UAAU,UAAU;EAC1B;EAAa,MAAM,UAAU,UAAU,OAAO,KAAKA,SAAW;;EAC9D,OAAO;EAAW;;wBAER,MAAM,UAAU,UAAU,aAAa,QAAQ,GAAG,gBAAgB,OAAO;wBA4BnE,qBAAqB,gBAAgB,gBAAa"}
1
+ {"version":3,"file":"valid.d.cts","names":["outputMini"],"sources":["../../src/utils/valid.ts"],"mappings":";;KAIK,OAAO,UAAU,UAAU,eAAe,UAAU,UAAU,OAAO,KAAKA,SAAW;;wBAGpE,SAAS,SAAS,UAAU;;wBAS5B,SAAS,SAAS,UAAU,QAAQ;;wBAS1C,MAAM,UAAU,UAAU,aAAa,QAAQ,GAAG,iBAAiB,OAAO;wBAcpE,qBAAqB,gBAAgB,gBAAgB"}
@@ -1,27 +1,12 @@
1
1
  import { ZodMiniType, output } from "zod/mini";
2
2
  import { ZodType, output as output$1 } from "zod";
3
- type ErrorBody = {
4
- error: {
5
- code: number;
6
- status: string;
7
- message: string;
8
- details: unknown[];
9
- };
10
- };
11
- export declare function invalidArgument(reason: string): ErrorBody;
12
- export declare function resourceExhausted(reason: string, message: string): ErrorBody;
13
- type Result<S extends ZodType | ZodMiniType> = {
14
- error: null;
15
- data: S extends ZodType ? output$1<S> : output<S>;
16
- } | {
17
- error: ErrorBody;
18
- data: null;
19
- };
20
- export declare function valid<S extends ZodType | ZodMiniType>(schema: S, json: unknown): Result<S>;
21
- export declare function verifyTurnstileToken(secret: string, token: string): Promise<{
22
- error: null;
23
- } | {
24
- error: ErrorBody;
25
- }>;
3
+ type Output<S extends ZodType | ZodMiniType> = S extends ZodType ? output$1<S> : output<S>;
4
+ /** The body as JSON, or a 400 for one that is not JSON. */
5
+ export declare function readJson(request: Request): Promise<unknown>;
6
+ /** The body as a form, or a 400 for one that is not `application/x-www-form-urlencoded`. */
7
+ export declare function readForm(request: Request): Promise<Record<string, string>>;
8
+ /** `value` as `schema` reads it, or a 400 `BadRequest` naming each field that failed. */
9
+ export declare function parse<S extends ZodType | ZodMiniType>(schema: S, value: unknown): Output<S>;
10
+ export declare function verifyTurnstileToken(secret: string, token: string): Promise<void>;
26
11
  export {};
27
12
  //# sourceMappingURL=valid.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"valid.d.mts","names":["output","outputMini"],"sources":["../../src/utils/valid.ts"],"mappings":";;KAGK;EACH;IACE;IACA;IACA;IACA;;;wBAIY,gBAAgB,iBAAiB;wBAWjC,kBAAkB,gBAAgB,kBAAkB;KAW/D,OAAO,UAAU,UAAU;EAC1B;EAAa,MAAM,UAAU,UAAUA,SAAO,KAAKC,OAAW;;EAC9D,OAAO;EAAW;;wBAER,MAAM,UAAU,UAAU,aAAa,QAAQ,GAAG,gBAAgB,OAAO;wBA4BnE,qBAAqB,gBAAgB,gBAAa"}
1
+ {"version":3,"file":"valid.d.mts","names":["output","outputMini"],"sources":["../../src/utils/valid.ts"],"mappings":";;KAIK,OAAO,UAAU,UAAU,eAAe,UAAU,UAAUA,SAAO,KAAKC,OAAW;;wBAGpE,SAAS,SAAS,UAAU;;wBAS5B,SAAS,SAAS,UAAU,QAAQ;;wBAS1C,MAAM,UAAU,UAAU,aAAa,QAAQ,GAAG,iBAAiB,OAAO;wBAcpE,qBAAqB,gBAAgB,gBAAgB"}
@@ -1,64 +1,46 @@
1
+ import { invalidArgument } from "../auth/respond.mjs";
1
2
  // src/utils/valid.ts
2
- function invalidArgument(reason) {
3
- return { error: {
4
- code: 400,
5
- status: "INVALID_ARGUMENT",
6
- message: "Invalid verification code",
7
- details: [{
8
- "@type": "type.googleapis.com/google.rpc.ErrorInfo",
9
- reason
10
- }]
11
- } };
3
+ /** The body as JSON, or a 400 for one that is not JSON. */
4
+ async function readJson(request) {
5
+ try {
6
+ return await request.json();
7
+ } catch {
8
+ throw invalidArgument("INVALID_JSON", "Request body is not valid JSON");
9
+ }
12
10
  }
13
- function resourceExhausted(reason, message) {
14
- return { error: {
15
- code: 429,
16
- status: "RESOURCE_EXHAUSTED",
17
- message,
18
- details: [{
19
- "@type": "type.googleapis.com/google.rpc.ErrorInfo",
20
- reason
21
- }]
22
- } };
11
+ /** The body as a form, or a 400 for one that is not `application/x-www-form-urlencoded`. */
12
+ async function readForm(request) {
13
+ if (!(request.headers.get("content-type")?.toLowerCase() ?? "").startsWith("application/x-www-form-urlencoded")) throw invalidArgument("INVALID_CONTENT_TYPE", "Expected application/x-www-form-urlencoded");
14
+ return Object.fromEntries(new URLSearchParams(await request.text()));
23
15
  }
24
- function valid(schema, json) {
25
- const result = schema.safeParse(json);
26
- if (result.success) return {
27
- error: null,
28
- data: result.data
29
- };
30
- return {
31
- error: { error: {
32
- code: 400,
33
- status: "INVALID_ARGUMENT",
34
- message: "Invalid request",
35
- details: [{
36
- "@type": "type.googleapis.com/google.rpc.BadRequest",
37
- fieldViolations: result.error.issues.map(({ code, path, message }) => ({
38
- field: path.join("."),
39
- description: message,
40
- reason: code.toUpperCase(),
41
- localizedMessage: {
42
- locale: "en-US",
43
- message
44
- }
45
- }))
46
- }]
47
- } },
48
- data: null
49
- };
16
+ /** `value` as `schema` reads it, or a 400 `BadRequest` naming each field that failed. */
17
+ function parse(schema, value) {
18
+ const result = schema.safeParse(value);
19
+ if (result.success) return result.data;
20
+ const fieldViolations = result.error.issues.map(({ code, path, message }) => ({
21
+ field: path.join("."),
22
+ description: message,
23
+ reason: code.toUpperCase(),
24
+ localizedMessage: {
25
+ locale: "en-US",
26
+ message
27
+ }
28
+ }));
29
+ throw invalidArgument("INVALID_ARGUMENT", "Invalid request", [{
30
+ "@type": "type.googleapis.com/google.rpc.BadRequest",
31
+ fieldViolations
32
+ }]);
50
33
  }
51
34
  async function verifyTurnstileToken(secret, token) {
52
- if ((await (await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
35
+ if (!(await (await fetch("https://challenges.cloudflare.com/turnstile/v0/siteverify", {
53
36
  method: "POST",
54
37
  headers: { "Content-Type": "application/x-www-form-urlencoded" },
55
38
  body: new URLSearchParams({
56
39
  secret,
57
40
  response: token
58
41
  })
59
- })).json()).success) return { error: null };
60
- return { error: invalidArgument("TURNSTILE_VERIFICATION_FAILED") };
42
+ })).json()).success) throw invalidArgument("TURNSTILE_VERIFICATION_FAILED", "Turnstile verification failed");
61
43
  }
62
- export { invalidArgument, resourceExhausted, valid, verifyTurnstileToken };
44
+ export { parse, readForm, readJson, verifyTurnstileToken };
63
45
 
64
46
  //# sourceMappingURL=valid.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"valid.mjs","names":[],"sources":["../../src/utils/valid.ts"],"sourcesContent":["import type { ZodType, output } from 'zod';\nimport type { ZodMiniType, output as outputMini } from 'zod/mini';\n\ntype ErrorBody = {\n error: {\n code: number;\n status: string;\n message: string;\n details: unknown[];\n };\n};\n\nexport function invalidArgument(reason: string): ErrorBody {\n return {\n error: {\n code: 400,\n status: 'INVALID_ARGUMENT',\n message: 'Invalid verification code',\n details: [{ '@type': 'type.googleapis.com/google.rpc.ErrorInfo', reason }],\n },\n };\n}\n\nexport function resourceExhausted(reason: string, message: string): ErrorBody {\n return {\n error: {\n code: 429,\n status: 'RESOURCE_EXHAUSTED',\n message,\n details: [{ '@type': 'type.googleapis.com/google.rpc.ErrorInfo', reason }],\n },\n };\n}\n\ntype Result<S extends ZodType | ZodMiniType> =\n | { error: null; data: S extends ZodType ? output<S> : outputMini<S> }\n | { error: ErrorBody; data: null };\n\nexport function valid<S extends ZodType | ZodMiniType>(schema: S, json: unknown): Result<S> {\n const result = schema.safeParse(json);\n if (result.success) {\n return {\n error: null,\n data: result.data as S extends ZodType ? output<S> : outputMini<S>,\n };\n }\n\n const fieldViolations = result.error.issues.map(({ code, path, message }) => ({\n field: path.join('.'),\n description: message,\n reason: code.toUpperCase(),\n localizedMessage: { locale: 'en-US', message },\n }));\n\n const error = {\n error: {\n code: 400,\n status: 'INVALID_ARGUMENT',\n message: 'Invalid request',\n details: [{ '@type': 'type.googleapis.com/google.rpc.BadRequest', fieldViolations }],\n },\n };\n\n return { error, data: null };\n}\n\nexport async function verifyTurnstileToken(secret: string, token: string) {\n const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({ secret, response: token }),\n });\n\n const data = (await response.json()) as { success: boolean };\n if (data.success) return { error: null };\n return { error: invalidArgument('TURNSTILE_VERIFICATION_FAILED') };\n}\n"],"mappings":";AAYA,SAAgB,gBAAgB,QAA2B;CACzD,OAAO,EACL,OAAO;EACL,MAAM;EACN,QAAQ;EACR,SAAS;EACT,SAAS,CAAC;GAAE,SAAS;GAA4C;EAAO,CAAC;CAC3E,EACF;AACF;AAEA,SAAgB,kBAAkB,QAAgB,SAA4B;CAC5E,OAAO,EACL,OAAO;EACL,MAAM;EACN,QAAQ;EACR;EACA,SAAS,CAAC;GAAE,SAAS;GAA4C;EAAO,CAAC;CAC3E,EACF;AACF;AAMA,SAAgB,MAAuC,QAAW,MAA0B;CAC1F,MAAM,SAAS,OAAO,UAAU,IAAI;CACpC,IAAI,OAAO,SACT,OAAO;EACL,OAAO;EACP,MAAM,OAAO;CACf;CAmBF,OAAO;EAAE,OAAA,EARP,OAAO;GACL,MAAM;GACN,QAAQ;GACR,SAAS;GACT,SAAS,CAAC;IAAE,SAAS;IAA6C,iBAZ9C,OAAO,MAAM,OAAO,KAAK,EAAE,MAAM,MAAM,eAAe;KAC5E,OAAO,KAAK,KAAK,GAAG;KACpB,aAAa;KACb,QAAQ,KAAK,YAAY;KACzB,kBAAkB;MAAE,QAAQ;MAAS;KAAQ;IAC/C,EAOoF;GAAE,CAAC;EACrF,EAGW;EAAG,MAAM;CAAK;AAC7B;AAEA,eAAsB,qBAAqB,QAAgB,OAAe;CAQxE,KAAI,OADgB,MANG,MAAM,6DAA6D;EACxF,QAAQ;EACR,SAAS,EAAE,gBAAgB,oCAAoC;EAC/D,MAAM,IAAI,gBAAgB;GAAE;GAAQ,UAAU;EAAM,CAAC;CACvD,CAAC,EAAA,CAE4B,KAAK,EAAA,CACzB,SAAS,OAAO,EAAE,OAAO,KAAK;CACvC,OAAO,EAAE,OAAO,gBAAgB,+BAA+B,EAAE;AACnE"}
1
+ {"version":3,"file":"valid.mjs","names":[],"sources":["../../src/utils/valid.ts"],"sourcesContent":["import type { ZodType, output } from 'zod';\nimport type { ZodMiniType, output as outputMini } from 'zod/mini';\nimport { invalidArgument } from '../auth/respond';\n\ntype Output<S extends ZodType | ZodMiniType> = S extends ZodType ? output<S> : outputMini<S>;\n\n/** The body as JSON, or a 400 for one that is not JSON. */\nexport async function readJson(request: Request): Promise<unknown> {\n try {\n return await request.json();\n } catch {\n throw invalidArgument('INVALID_JSON', 'Request body is not valid JSON');\n }\n}\n\n/** The body as a form, or a 400 for one that is not `application/x-www-form-urlencoded`. */\nexport async function readForm(request: Request): Promise<Record<string, string>> {\n const type = request.headers.get('content-type')?.toLowerCase() ?? '';\n if (!type.startsWith('application/x-www-form-urlencoded')) {\n throw invalidArgument('INVALID_CONTENT_TYPE', 'Expected application/x-www-form-urlencoded');\n }\n return Object.fromEntries(new URLSearchParams(await request.text()));\n}\n\n/** `value` as `schema` reads it, or a 400 `BadRequest` naming each field that failed. */\nexport function parse<S extends ZodType | ZodMiniType>(schema: S, value: unknown): Output<S> {\n const result = schema.safeParse(value);\n if (result.success) return result.data as Output<S>;\n const fieldViolations = result.error.issues.map(({ code, path, message }) => ({\n field: path.join('.'),\n description: message,\n reason: code.toUpperCase(),\n localizedMessage: { locale: 'en-US', message },\n }));\n throw invalidArgument('INVALID_ARGUMENT', 'Invalid request', [\n { '@type': 'type.googleapis.com/google.rpc.BadRequest', fieldViolations },\n ]);\n}\n\nexport async function verifyTurnstileToken(secret: string, token: string): Promise<void> {\n const response = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({ secret, response: token }),\n });\n const data = (await response.json()) as { success: boolean };\n if (!data.success) {\n throw invalidArgument('TURNSTILE_VERIFICATION_FAILED', 'Turnstile verification failed');\n }\n}\n"],"mappings":";;;AAOA,eAAsB,SAAS,SAAoC;CACjE,IAAI;EACF,OAAO,MAAM,QAAQ,KAAK;CAC5B,QAAQ;EACN,MAAM,gBAAgB,gBAAgB,gCAAgC;CACxE;AACF;;AAGA,eAAsB,SAAS,SAAmD;CAEhF,IAAI,EADS,QAAQ,QAAQ,IAAI,cAAc,CAAC,EAAE,YAAY,KAAK,GAAA,CACzD,WAAW,mCAAmC,GACtD,MAAM,gBAAgB,wBAAwB,4CAA4C;CAE5F,OAAO,OAAO,YAAY,IAAI,gBAAgB,MAAM,QAAQ,KAAK,CAAC,CAAC;AACrE;;AAGA,SAAgB,MAAuC,QAAW,OAA2B;CAC3F,MAAM,SAAS,OAAO,UAAU,KAAK;CACrC,IAAI,OAAO,SAAS,OAAO,OAAO;CAClC,MAAM,kBAAkB,OAAO,MAAM,OAAO,KAAK,EAAE,MAAM,MAAM,eAAe;EAC5E,OAAO,KAAK,KAAK,GAAG;EACpB,aAAa;EACb,QAAQ,KAAK,YAAY;EACzB,kBAAkB;GAAE,QAAQ;GAAS;EAAQ;CAC/C,EAAE;CACF,MAAM,gBAAgB,oBAAoB,mBAAmB,CAC3D;EAAE,SAAS;EAA6C;CAAgB,CAC1E,CAAC;AACH;AAEA,eAAsB,qBAAqB,QAAgB,OAA8B;CAOvF,IAAI,EAAC,OADe,MALG,MAAM,6DAA6D;EACxF,QAAQ;EACR,SAAS,EAAE,gBAAgB,oCAAoC;EAC/D,MAAM,IAAI,gBAAgB;GAAE;GAAQ,UAAU;EAAM,CAAC;CACvD,CAAC,EAAA,CAC4B,KAAK,EAAA,CACxB,SACR,MAAM,gBAAgB,iCAAiC,+BAA+B;AAE1F"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shware/security",
3
- "version": "7.1.1",
3
+ "version": "8.0.1",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,7 +36,7 @@
36
36
  "access": "public"
37
37
  },
38
38
  "dependencies": {
39
- "@shware/utils": "^2.0.1",
39
+ "@shware/utils": "^2.0.2",
40
40
  "cookie": "^2.0.1",
41
41
  "jose": "^6.2.13",
42
42
  "path-to-regexp": "^8.4.2"
@@ -62,7 +62,7 @@
62
62
  "dev": "tsc --watch",
63
63
  "build": "tsdown",
64
64
  "test": "vitest run",
65
- "check-types": "tsc --noEmit",
65
+ "check-types": "tsc --noEmit && tsc --noEmit -p tsconfig.typetests.json",
66
66
  "lint": "oxlint --type-aware src --fix"
67
67
  }
68
68
  }