@shware/security 0.4.3

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 (128) hide show
  1. package/README.md +1 -0
  2. package/dist/auth/index.cjs +158 -0
  3. package/dist/auth/index.cjs.map +1 -0
  4. package/dist/auth/index.d.cts +27 -0
  5. package/dist/auth/index.d.ts +27 -0
  6. package/dist/auth/index.mjs +129 -0
  7. package/dist/auth/index.mjs.map +1 -0
  8. package/dist/auth/types.cjs +19 -0
  9. package/dist/auth/types.cjs.map +1 -0
  10. package/dist/auth/types.d.cts +25 -0
  11. package/dist/auth/types.d.ts +25 -0
  12. package/dist/auth/types.mjs +1 -0
  13. package/dist/auth/types.mjs.map +1 -0
  14. package/dist/core/index.cjs +19 -0
  15. package/dist/core/index.cjs.map +1 -0
  16. package/dist/core/index.d.cts +17 -0
  17. package/dist/core/index.d.ts +17 -0
  18. package/dist/core/index.mjs +1 -0
  19. package/dist/core/index.mjs.map +1 -0
  20. package/dist/index.cjs +41 -0
  21. package/dist/index.cjs.map +1 -0
  22. package/dist/index.d.cts +11 -0
  23. package/dist/index.d.ts +11 -0
  24. package/dist/index.mjs +12 -0
  25. package/dist/index.mjs.map +1 -0
  26. package/dist/oauth2/client.cjs +110 -0
  27. package/dist/oauth2/client.cjs.map +1 -0
  28. package/dist/oauth2/client.d.cts +39 -0
  29. package/dist/oauth2/client.d.ts +39 -0
  30. package/dist/oauth2/client.mjs +74 -0
  31. package/dist/oauth2/client.mjs.map +1 -0
  32. package/dist/oauth2/error.cjs +54 -0
  33. package/dist/oauth2/error.cjs.map +1 -0
  34. package/dist/oauth2/error.d.cts +11 -0
  35. package/dist/oauth2/error.d.ts +11 -0
  36. package/dist/oauth2/error.mjs +28 -0
  37. package/dist/oauth2/error.mjs.map +1 -0
  38. package/dist/oauth2/provider/apple.cjs +85 -0
  39. package/dist/oauth2/provider/apple.cjs.map +1 -0
  40. package/dist/oauth2/provider/apple.d.cts +31 -0
  41. package/dist/oauth2/provider/apple.d.ts +31 -0
  42. package/dist/oauth2/provider/apple.mjs +50 -0
  43. package/dist/oauth2/provider/apple.mjs.map +1 -0
  44. package/dist/oauth2/provider/common.cjs +159 -0
  45. package/dist/oauth2/provider/common.cjs.map +1 -0
  46. package/dist/oauth2/provider/common.d.cts +38 -0
  47. package/dist/oauth2/provider/common.d.ts +38 -0
  48. package/dist/oauth2/provider/common.mjs +119 -0
  49. package/dist/oauth2/provider/common.mjs.map +1 -0
  50. package/dist/oauth2/provider/facebook.cjs +106 -0
  51. package/dist/oauth2/provider/facebook.cjs.map +1 -0
  52. package/dist/oauth2/provider/facebook.d.cts +29 -0
  53. package/dist/oauth2/provider/facebook.d.ts +29 -0
  54. package/dist/oauth2/provider/facebook.mjs +71 -0
  55. package/dist/oauth2/provider/facebook.mjs.map +1 -0
  56. package/dist/oauth2/provider/github.cjs +101 -0
  57. package/dist/oauth2/provider/github.cjs.map +1 -0
  58. package/dist/oauth2/provider/github.d.cts +51 -0
  59. package/dist/oauth2/provider/github.d.ts +51 -0
  60. package/dist/oauth2/provider/github.mjs +66 -0
  61. package/dist/oauth2/provider/github.mjs.map +1 -0
  62. package/dist/oauth2/provider/google.cjs +91 -0
  63. package/dist/oauth2/provider/google.cjs.map +1 -0
  64. package/dist/oauth2/provider/google.d.cts +35 -0
  65. package/dist/oauth2/provider/google.d.ts +35 -0
  66. package/dist/oauth2/provider/google.mjs +56 -0
  67. package/dist/oauth2/provider/google.mjs.map +1 -0
  68. package/dist/oauth2/provider/index.cjs +43 -0
  69. package/dist/oauth2/provider/index.cjs.map +1 -0
  70. package/dist/oauth2/provider/index.d.cts +6 -0
  71. package/dist/oauth2/provider/index.d.ts +6 -0
  72. package/dist/oauth2/provider/index.mjs +14 -0
  73. package/dist/oauth2/provider/index.mjs.map +1 -0
  74. package/dist/oauth2/provider/x.cjs +126 -0
  75. package/dist/oauth2/provider/x.cjs.map +1 -0
  76. package/dist/oauth2/provider/x.d.cts +60 -0
  77. package/dist/oauth2/provider/x.d.ts +60 -0
  78. package/dist/oauth2/provider/x.mjs +97 -0
  79. package/dist/oauth2/provider/x.mjs.map +1 -0
  80. package/dist/oauth2/schema.cjs +2 -0
  81. package/dist/oauth2/schema.cjs.map +1 -0
  82. package/dist/oauth2/schema.d.cts +2 -0
  83. package/dist/oauth2/schema.d.ts +2 -0
  84. package/dist/oauth2/schema.mjs +1 -0
  85. package/dist/oauth2/schema.mjs.map +1 -0
  86. package/dist/oauth2/types.cjs +19 -0
  87. package/dist/oauth2/types.cjs.map +1 -0
  88. package/dist/oauth2/types.d.cts +138 -0
  89. package/dist/oauth2/types.d.ts +138 -0
  90. package/dist/oauth2/types.mjs +1 -0
  91. package/dist/oauth2/types.mjs.map +1 -0
  92. package/dist/oidc/index.cjs +39 -0
  93. package/dist/oidc/index.cjs.map +1 -0
  94. package/dist/oidc/index.d.cts +10 -0
  95. package/dist/oidc/index.d.ts +10 -0
  96. package/dist/oidc/index.mjs +14 -0
  97. package/dist/oidc/index.mjs.map +1 -0
  98. package/dist/session/__test__/redis-session.test.cjs +94 -0
  99. package/dist/session/__test__/redis-session.test.cjs.map +1 -0
  100. package/dist/session/__test__/redis-session.test.d.cts +2 -0
  101. package/dist/session/__test__/redis-session.test.d.ts +2 -0
  102. package/dist/session/__test__/redis-session.test.mjs +70 -0
  103. package/dist/session/__test__/redis-session.test.mjs.map +1 -0
  104. package/dist/session/index.cjs +33 -0
  105. package/dist/session/index.cjs.map +1 -0
  106. package/dist/session/index.d.cts +4 -0
  107. package/dist/session/index.d.ts +4 -0
  108. package/dist/session/index.mjs +7 -0
  109. package/dist/session/index.mjs.map +1 -0
  110. package/dist/session/redis-session.cjs +403 -0
  111. package/dist/session/redis-session.cjs.map +1 -0
  112. package/dist/session/redis-session.d.cts +73 -0
  113. package/dist/session/redis-session.d.ts +73 -0
  114. package/dist/session/redis-session.mjs +377 -0
  115. package/dist/session/redis-session.mjs.map +1 -0
  116. package/dist/session/types.cjs +19 -0
  117. package/dist/session/types.cjs.map +1 -0
  118. package/dist/session/types.d.cts +39 -0
  119. package/dist/session/types.d.ts +39 -0
  120. package/dist/session/types.mjs +1 -0
  121. package/dist/session/types.mjs.map +1 -0
  122. package/dist/utils/http.cjs +63 -0
  123. package/dist/utils/http.cjs.map +1 -0
  124. package/dist/utils/http.d.cts +17 -0
  125. package/dist/utils/http.d.ts +17 -0
  126. package/dist/utils/http.mjs +34 -0
  127. package/dist/utils/http.mjs.map +1 -0
  128. package/package.json +44 -0
package/README.md ADDED
@@ -0,0 +1 @@
1
+ # Auth lib
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
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
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/auth/index.ts
31
+ var auth_exports = {};
32
+ __export(auth_exports, {
33
+ Auth: () => Auth
34
+ });
35
+ module.exports = __toCommonJS(auth_exports);
36
+ var import_crypto = require("crypto");
37
+ var import_tiny_invariant = __toESM(require("tiny-invariant"), 1);
38
+ var import_session = require("../session.cjs");
39
+ var import_http = require("../utils/http.cjs");
40
+ var import_client = require("../oauth2/client.cjs");
41
+ var Auth = class {
42
+ cookieName;
43
+ cookieOptions;
44
+ repository;
45
+ oauth2Client;
46
+ PATH_CSRF = "/csrf";
47
+ PATH_LOGOUT = "/logout";
48
+ PATH_LOGGED = "/logged";
49
+ PATH_OAUTH2_AUTHORIZATION = "/oauth2/authorization/:registrationId";
50
+ PATH_OAUTH2_REDIRECT = "/login/oauth2/code/:registrationId";
51
+ ATTR_OAUTH2_AUTHORIZATION_REQUEST = "oauth2AuthorizationRequest";
52
+ constructor({ repository, oauth2, cookie }) {
53
+ this.repository = repository;
54
+ const { name, ...cookieOptions } = cookie ?? {};
55
+ this.cookieName = name ?? "SESSION";
56
+ this.cookieOptions = {
57
+ path: "/",
58
+ sameSite: "none",
59
+ secure: true,
60
+ httpOnly: true,
61
+ ...cookieOptions
62
+ };
63
+ this.oauth2Client = oauth2?.client ? new import_client.OAuth2Client(oauth2.client) : null;
64
+ }
65
+ logout = async (request) => {
66
+ const sessionId = (0, import_http.getCookie)(request, this.cookieName);
67
+ if (sessionId) await this.repository.deleteById(sessionId);
68
+ const response = Response.json({});
69
+ (0, import_http.deleteCookie)(response, this.cookieName);
70
+ return response;
71
+ };
72
+ logged = async (request, onLogged) => {
73
+ const sessionId = (0, import_http.getCookie)(request, this.cookieName);
74
+ if (!sessionId) return Response.json({ data: false });
75
+ const session = await this.repository.findById(sessionId);
76
+ if (!session) return Response.json({ data: false });
77
+ const name = session.getAttribute(import_session.PRINCIPAL_NAME_INDEX_NAME);
78
+ session.setLastAccessedTime(Date.now());
79
+ await this.repository.save(session);
80
+ if (name !== null) await onLogged?.({ name: String(name) });
81
+ const response = Response.json({ data: name !== null });
82
+ const maxAge = session.getMaxInactiveInterval();
83
+ (0, import_http.setCookie)(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });
84
+ return response;
85
+ };
86
+ oauth2Authorization = async (request) => {
87
+ (0, import_tiny_invariant.default)(this.oauth2Client, "oauth2Client is not initialized");
88
+ const { registrationId } = (0, import_http.param)(request, this.PATH_OAUTH2_AUTHORIZATION);
89
+ const state = (0, import_crypto.randomUUID)();
90
+ const codeVerifier = (0, import_crypto.randomUUID)();
91
+ const uri = this.oauth2Client.createAuthorizationUri(registrationId, state, codeVerifier);
92
+ const sessionId = (0, import_http.getCookie)(request, this.cookieName);
93
+ const session = sessionId ? await this.repository.findById(sessionId) ?? this.repository.createSession() : this.repository.createSession();
94
+ const authorizationRequest = {
95
+ state,
96
+ codeVerifier,
97
+ registrationId,
98
+ authorizationRequestUri: uri.href
99
+ };
100
+ const value = JSON.stringify(authorizationRequest);
101
+ session.setAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST, value);
102
+ await this.repository.save(session);
103
+ const response = Response.redirect(uri.href, 302);
104
+ const maxAge = session.getMaxInactiveInterval();
105
+ (0, import_http.setCookie)(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });
106
+ return response;
107
+ };
108
+ redirect = (error) => {
109
+ (0, import_tiny_invariant.default)(this.oauth2Client, "oauth2Client is not initialized");
110
+ return Response.redirect(`${this.oauth2Client.errorUri}?error=${error}`, 302);
111
+ };
112
+ loginOAuth2 = async (request, onAuthorized) => {
113
+ (0, import_tiny_invariant.default)(this.oauth2Client, "oauth2Client is not initialized");
114
+ const sessionId = (0, import_http.getCookie)(request, this.cookieName);
115
+ const session = sessionId ? await this.repository.findById(sessionId) : null;
116
+ if (!session) {
117
+ return this.redirect("OAUTH2_AUTHORIZATION_SESSION_NOT_FOUND");
118
+ }
119
+ const json = session.getAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST);
120
+ if (!json) {
121
+ return this.redirect("OAUTH2_AUTHORIZATION_REQUEST_NOT_FOUND");
122
+ }
123
+ const cached = JSON.parse(json);
124
+ const { registrationId } = (0, import_http.param)(request, this.PATH_OAUTH2_REDIRECT);
125
+ const parsed = import_client.oauth2RedirectQuerySchema.safeParse((0, import_http.query)(request));
126
+ if (!parsed.success) {
127
+ return this.redirect("INVALID_OAUTH2_REDIRECT_QUERY");
128
+ }
129
+ if (parsed.data.state !== cached.state) {
130
+ return this.redirect("INVALID_OAUTH2_REDIRECT_STATE");
131
+ }
132
+ if (registrationId !== cached.registrationId) {
133
+ return this.redirect("INVALID_OAUTH2_REDIRECT_REGISTRATION_ID");
134
+ }
135
+ const { code } = parsed.data;
136
+ const { codeVerifier } = cached;
137
+ const token = await this.oauth2Client.exchangeAuthorizationCode(
138
+ registrationId,
139
+ code,
140
+ codeVerifier
141
+ );
142
+ const userInfo = await this.oauth2Client.getUserInfo(registrationId, token);
143
+ const principal = await onAuthorized(request, registrationId, userInfo, token);
144
+ session.setLastAccessedTime(Date.now());
145
+ session.removeAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST);
146
+ session.setAttribute(import_session.PRINCIPAL_NAME_INDEX_NAME, principal.name);
147
+ await this.repository.save(session);
148
+ const response = Response.redirect(this.oauth2Client.baseUri, 302);
149
+ const maxAge = session.getMaxInactiveInterval();
150
+ (0, import_http.setCookie)(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });
151
+ return response;
152
+ };
153
+ };
154
+ // Annotate the CommonJS export names for ESM import in node:
155
+ 0 && (module.exports = {
156
+ Auth
157
+ });
158
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/auth/index.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport invariant from 'tiny-invariant';\nimport { PRINCIPAL_NAME_INDEX_NAME, type SessionRepository } from '../session';\nimport {\n param,\n query,\n getCookie,\n setCookie,\n deleteCookie,\n type CookieOptions,\n} from '../utils/http';\nimport { OAuth2Client, oauth2RedirectQuerySchema } from '../oauth2/client';\nimport type { OAuth2AuthorizationRequest } from '../oauth2/types';\nimport type { AuthConfig, AuthService, LoggedHandler, OAuth2AuthorizedHandler } from './types';\n\nexport class Auth implements AuthService {\n private readonly cookieName;\n private readonly cookieOptions: CookieOptions;\n private readonly repository: SessionRepository;\n private readonly oauth2Client: OAuth2Client | null;\n\n public readonly PATH_CSRF = '/csrf' as const;\n public readonly PATH_LOGOUT = '/logout' as const;\n public readonly PATH_LOGGED = '/logged' as const;\n\n public readonly PATH_OAUTH2_AUTHORIZATION = '/oauth2/authorization/:registrationId' as const;\n public readonly PATH_OAUTH2_REDIRECT = '/login/oauth2/code/:registrationId' as const;\n\n public readonly ATTR_OAUTH2_AUTHORIZATION_REQUEST = 'oauth2AuthorizationRequest';\n\n constructor({ repository, oauth2, cookie }: AuthConfig) {\n this.repository = repository;\n const { name, ...cookieOptions } = cookie ?? {};\n this.cookieName = name ?? 'SESSION';\n this.cookieOptions = {\n path: '/',\n sameSite: 'none',\n secure: true,\n httpOnly: true,\n ...cookieOptions,\n };\n this.oauth2Client = oauth2?.client ? new OAuth2Client(oauth2.client) : null;\n }\n\n logout = async (request: Request): Promise<Response> => {\n const sessionId = getCookie(request, this.cookieName);\n if (sessionId) await this.repository.deleteById(sessionId);\n const response = Response.json({});\n deleteCookie(response, this.cookieName);\n return response;\n };\n\n logged = async (request: Request, onLogged?: LoggedHandler): Promise<Response> => {\n // 1. get session from cookie\n const sessionId = getCookie(request, this.cookieName);\n if (!sessionId) return Response.json({ data: false });\n const session = await this.repository.findById(sessionId);\n if (!session) return Response.json({ data: false });\n\n // 2. get principal name from session\n const name = session.getAttribute(PRINCIPAL_NAME_INDEX_NAME);\n session.setLastAccessedTime(Date.now());\n await this.repository.save(session);\n\n // 3. call onLogged\n if (name !== null) await onLogged?.({ name: String(name) });\n\n // 4. renew cookie\n const response = Response.json({ data: name !== null });\n const maxAge = session.getMaxInactiveInterval();\n setCookie(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });\n\n return response;\n };\n\n oauth2Authorization = async (request: Request): Promise<Response> => {\n invariant(this.oauth2Client, 'oauth2Client is not initialized');\n const { registrationId } = param(request, this.PATH_OAUTH2_AUTHORIZATION);\n const state = randomUUID();\n const codeVerifier = randomUUID();\n const uri = this.oauth2Client.createAuthorizationUri(registrationId, state, codeVerifier);\n const sessionId = getCookie(request, this.cookieName);\n const session = sessionId\n ? ((await this.repository.findById(sessionId)) ?? this.repository.createSession())\n : this.repository.createSession();\n\n const authorizationRequest: OAuth2AuthorizationRequest = {\n state,\n codeVerifier,\n registrationId,\n authorizationRequestUri: uri.href,\n };\n\n const value = JSON.stringify(authorizationRequest);\n session.setAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST, value);\n await this.repository.save(session);\n\n const response = Response.redirect(uri.href, 302);\n const maxAge = session.getMaxInactiveInterval();\n setCookie(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });\n return response;\n };\n\n private redirect = (error: string): Response => {\n invariant(this.oauth2Client, 'oauth2Client is not initialized');\n return Response.redirect(`${this.oauth2Client.errorUri}?error=${error}`, 302);\n };\n\n loginOAuth2 = async (\n request: Request,\n onAuthorized: OAuth2AuthorizedHandler\n ): Promise<Response> => {\n invariant(this.oauth2Client, 'oauth2Client is not initialized');\n\n // 1. get session from cookie\n const sessionId = getCookie(request, this.cookieName);\n const session = sessionId ? await this.repository.findById(sessionId) : null;\n if (!session) {\n return this.redirect('OAUTH2_AUTHORIZATION_SESSION_NOT_FOUND');\n }\n\n // 2. get cached authorization request from session\n const json = session.getAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST) as string | null;\n if (!json) {\n return this.redirect('OAUTH2_AUTHORIZATION_REQUEST_NOT_FOUND');\n }\n const cached: OAuth2AuthorizationRequest = JSON.parse(json);\n\n // 3. validate redirect query\n const { registrationId } = param(request, this.PATH_OAUTH2_REDIRECT);\n const parsed = oauth2RedirectQuerySchema.safeParse(query(request));\n if (!parsed.success) {\n return this.redirect('INVALID_OAUTH2_REDIRECT_QUERY');\n }\n if (parsed.data.state !== cached.state) {\n return this.redirect('INVALID_OAUTH2_REDIRECT_STATE');\n }\n if (registrationId !== cached.registrationId) {\n return this.redirect('INVALID_OAUTH2_REDIRECT_REGISTRATION_ID');\n }\n\n // 4. exchange authorization code for token and get user info\n const { code } = parsed.data;\n const { codeVerifier } = cached;\n const token = await this.oauth2Client.exchangeAuthorizationCode(\n registrationId,\n code,\n codeVerifier\n );\n const userInfo = await this.oauth2Client.getUserInfo(registrationId, token);\n\n // 5. create or update principal\n const principal = await onAuthorized(request, registrationId, userInfo, token);\n\n // 6. update session\n session.setLastAccessedTime(Date.now());\n session.removeAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST);\n session.setAttribute(PRINCIPAL_NAME_INDEX_NAME, principal.name);\n await this.repository.save(session);\n\n const response = Response.redirect(this.oauth2Client.baseUri, 302);\n const maxAge = session.getMaxInactiveInterval();\n setCookie(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });\n return response;\n };\n}\n"],"mappings":"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","names":["invariant"]}
@@ -0,0 +1,27 @@
1
+ import { AuthService, AuthConfig, LoggedHandler, OAuth2AuthorizedHandler } from './types.cjs';
2
+ import '../core/index.cjs';
3
+ import '../oauth2/types.cjs';
4
+ import '../session/types.cjs';
5
+ import '../utils/http.cjs';
6
+ import 'cookie';
7
+
8
+ declare class Auth implements AuthService {
9
+ private readonly cookieName;
10
+ private readonly cookieOptions;
11
+ private readonly repository;
12
+ private readonly oauth2Client;
13
+ readonly PATH_CSRF: "/csrf";
14
+ readonly PATH_LOGOUT: "/logout";
15
+ readonly PATH_LOGGED: "/logged";
16
+ readonly PATH_OAUTH2_AUTHORIZATION: "/oauth2/authorization/:registrationId";
17
+ readonly PATH_OAUTH2_REDIRECT: "/login/oauth2/code/:registrationId";
18
+ readonly ATTR_OAUTH2_AUTHORIZATION_REQUEST = "oauth2AuthorizationRequest";
19
+ constructor({ repository, oauth2, cookie }: AuthConfig);
20
+ logout: (request: Request) => Promise<Response>;
21
+ logged: (request: Request, onLogged?: LoggedHandler) => Promise<Response>;
22
+ oauth2Authorization: (request: Request) => Promise<Response>;
23
+ private redirect;
24
+ loginOAuth2: (request: Request, onAuthorized: OAuth2AuthorizedHandler) => Promise<Response>;
25
+ }
26
+
27
+ export { Auth };
@@ -0,0 +1,27 @@
1
+ import { AuthService, AuthConfig, LoggedHandler, OAuth2AuthorizedHandler } from './types.js';
2
+ import '../core/index.js';
3
+ import '../oauth2/types.js';
4
+ import '../session/types.js';
5
+ import '../utils/http.js';
6
+ import 'cookie';
7
+
8
+ declare class Auth implements AuthService {
9
+ private readonly cookieName;
10
+ private readonly cookieOptions;
11
+ private readonly repository;
12
+ private readonly oauth2Client;
13
+ readonly PATH_CSRF: "/csrf";
14
+ readonly PATH_LOGOUT: "/logout";
15
+ readonly PATH_LOGGED: "/logged";
16
+ readonly PATH_OAUTH2_AUTHORIZATION: "/oauth2/authorization/:registrationId";
17
+ readonly PATH_OAUTH2_REDIRECT: "/login/oauth2/code/:registrationId";
18
+ readonly ATTR_OAUTH2_AUTHORIZATION_REQUEST = "oauth2AuthorizationRequest";
19
+ constructor({ repository, oauth2, cookie }: AuthConfig);
20
+ logout: (request: Request) => Promise<Response>;
21
+ logged: (request: Request, onLogged?: LoggedHandler) => Promise<Response>;
22
+ oauth2Authorization: (request: Request) => Promise<Response>;
23
+ private redirect;
24
+ loginOAuth2: (request: Request, onAuthorized: OAuth2AuthorizedHandler) => Promise<Response>;
25
+ }
26
+
27
+ export { Auth };
@@ -0,0 +1,129 @@
1
+ // src/auth/index.ts
2
+ import { randomUUID } from "crypto";
3
+ import invariant from "tiny-invariant";
4
+ import { PRINCIPAL_NAME_INDEX_NAME } from "../session.mjs";
5
+ import {
6
+ param,
7
+ query,
8
+ getCookie,
9
+ setCookie,
10
+ deleteCookie
11
+ } from "../utils/http.mjs";
12
+ import { OAuth2Client, oauth2RedirectQuerySchema } from "../oauth2/client.mjs";
13
+ var Auth = class {
14
+ cookieName;
15
+ cookieOptions;
16
+ repository;
17
+ oauth2Client;
18
+ PATH_CSRF = "/csrf";
19
+ PATH_LOGOUT = "/logout";
20
+ PATH_LOGGED = "/logged";
21
+ PATH_OAUTH2_AUTHORIZATION = "/oauth2/authorization/:registrationId";
22
+ PATH_OAUTH2_REDIRECT = "/login/oauth2/code/:registrationId";
23
+ ATTR_OAUTH2_AUTHORIZATION_REQUEST = "oauth2AuthorizationRequest";
24
+ constructor({ repository, oauth2, cookie }) {
25
+ this.repository = repository;
26
+ const { name, ...cookieOptions } = cookie ?? {};
27
+ this.cookieName = name ?? "SESSION";
28
+ this.cookieOptions = {
29
+ path: "/",
30
+ sameSite: "none",
31
+ secure: true,
32
+ httpOnly: true,
33
+ ...cookieOptions
34
+ };
35
+ this.oauth2Client = oauth2?.client ? new OAuth2Client(oauth2.client) : null;
36
+ }
37
+ logout = async (request) => {
38
+ const sessionId = getCookie(request, this.cookieName);
39
+ if (sessionId) await this.repository.deleteById(sessionId);
40
+ const response = Response.json({});
41
+ deleteCookie(response, this.cookieName);
42
+ return response;
43
+ };
44
+ logged = async (request, onLogged) => {
45
+ const sessionId = getCookie(request, this.cookieName);
46
+ if (!sessionId) return Response.json({ data: false });
47
+ const session = await this.repository.findById(sessionId);
48
+ if (!session) return Response.json({ data: false });
49
+ const name = session.getAttribute(PRINCIPAL_NAME_INDEX_NAME);
50
+ session.setLastAccessedTime(Date.now());
51
+ await this.repository.save(session);
52
+ if (name !== null) await onLogged?.({ name: String(name) });
53
+ const response = Response.json({ data: name !== null });
54
+ const maxAge = session.getMaxInactiveInterval();
55
+ setCookie(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });
56
+ return response;
57
+ };
58
+ oauth2Authorization = async (request) => {
59
+ invariant(this.oauth2Client, "oauth2Client is not initialized");
60
+ const { registrationId } = param(request, this.PATH_OAUTH2_AUTHORIZATION);
61
+ const state = randomUUID();
62
+ const codeVerifier = randomUUID();
63
+ const uri = this.oauth2Client.createAuthorizationUri(registrationId, state, codeVerifier);
64
+ const sessionId = getCookie(request, this.cookieName);
65
+ const session = sessionId ? await this.repository.findById(sessionId) ?? this.repository.createSession() : this.repository.createSession();
66
+ const authorizationRequest = {
67
+ state,
68
+ codeVerifier,
69
+ registrationId,
70
+ authorizationRequestUri: uri.href
71
+ };
72
+ const value = JSON.stringify(authorizationRequest);
73
+ session.setAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST, value);
74
+ await this.repository.save(session);
75
+ const response = Response.redirect(uri.href, 302);
76
+ const maxAge = session.getMaxInactiveInterval();
77
+ setCookie(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });
78
+ return response;
79
+ };
80
+ redirect = (error) => {
81
+ invariant(this.oauth2Client, "oauth2Client is not initialized");
82
+ return Response.redirect(`${this.oauth2Client.errorUri}?error=${error}`, 302);
83
+ };
84
+ loginOAuth2 = async (request, onAuthorized) => {
85
+ invariant(this.oauth2Client, "oauth2Client is not initialized");
86
+ const sessionId = getCookie(request, this.cookieName);
87
+ const session = sessionId ? await this.repository.findById(sessionId) : null;
88
+ if (!session) {
89
+ return this.redirect("OAUTH2_AUTHORIZATION_SESSION_NOT_FOUND");
90
+ }
91
+ const json = session.getAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST);
92
+ if (!json) {
93
+ return this.redirect("OAUTH2_AUTHORIZATION_REQUEST_NOT_FOUND");
94
+ }
95
+ const cached = JSON.parse(json);
96
+ const { registrationId } = param(request, this.PATH_OAUTH2_REDIRECT);
97
+ const parsed = oauth2RedirectQuerySchema.safeParse(query(request));
98
+ if (!parsed.success) {
99
+ return this.redirect("INVALID_OAUTH2_REDIRECT_QUERY");
100
+ }
101
+ if (parsed.data.state !== cached.state) {
102
+ return this.redirect("INVALID_OAUTH2_REDIRECT_STATE");
103
+ }
104
+ if (registrationId !== cached.registrationId) {
105
+ return this.redirect("INVALID_OAUTH2_REDIRECT_REGISTRATION_ID");
106
+ }
107
+ const { code } = parsed.data;
108
+ const { codeVerifier } = cached;
109
+ const token = await this.oauth2Client.exchangeAuthorizationCode(
110
+ registrationId,
111
+ code,
112
+ codeVerifier
113
+ );
114
+ const userInfo = await this.oauth2Client.getUserInfo(registrationId, token);
115
+ const principal = await onAuthorized(request, registrationId, userInfo, token);
116
+ session.setLastAccessedTime(Date.now());
117
+ session.removeAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST);
118
+ session.setAttribute(PRINCIPAL_NAME_INDEX_NAME, principal.name);
119
+ await this.repository.save(session);
120
+ const response = Response.redirect(this.oauth2Client.baseUri, 302);
121
+ const maxAge = session.getMaxInactiveInterval();
122
+ setCookie(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });
123
+ return response;
124
+ };
125
+ };
126
+ export {
127
+ Auth
128
+ };
129
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/auth/index.ts"],"sourcesContent":["import { randomUUID } from 'crypto';\nimport invariant from 'tiny-invariant';\nimport { PRINCIPAL_NAME_INDEX_NAME, type SessionRepository } from '../session';\nimport {\n param,\n query,\n getCookie,\n setCookie,\n deleteCookie,\n type CookieOptions,\n} from '../utils/http';\nimport { OAuth2Client, oauth2RedirectQuerySchema } from '../oauth2/client';\nimport type { OAuth2AuthorizationRequest } from '../oauth2/types';\nimport type { AuthConfig, AuthService, LoggedHandler, OAuth2AuthorizedHandler } from './types';\n\nexport class Auth implements AuthService {\n private readonly cookieName;\n private readonly cookieOptions: CookieOptions;\n private readonly repository: SessionRepository;\n private readonly oauth2Client: OAuth2Client | null;\n\n public readonly PATH_CSRF = '/csrf' as const;\n public readonly PATH_LOGOUT = '/logout' as const;\n public readonly PATH_LOGGED = '/logged' as const;\n\n public readonly PATH_OAUTH2_AUTHORIZATION = '/oauth2/authorization/:registrationId' as const;\n public readonly PATH_OAUTH2_REDIRECT = '/login/oauth2/code/:registrationId' as const;\n\n public readonly ATTR_OAUTH2_AUTHORIZATION_REQUEST = 'oauth2AuthorizationRequest';\n\n constructor({ repository, oauth2, cookie }: AuthConfig) {\n this.repository = repository;\n const { name, ...cookieOptions } = cookie ?? {};\n this.cookieName = name ?? 'SESSION';\n this.cookieOptions = {\n path: '/',\n sameSite: 'none',\n secure: true,\n httpOnly: true,\n ...cookieOptions,\n };\n this.oauth2Client = oauth2?.client ? new OAuth2Client(oauth2.client) : null;\n }\n\n logout = async (request: Request): Promise<Response> => {\n const sessionId = getCookie(request, this.cookieName);\n if (sessionId) await this.repository.deleteById(sessionId);\n const response = Response.json({});\n deleteCookie(response, this.cookieName);\n return response;\n };\n\n logged = async (request: Request, onLogged?: LoggedHandler): Promise<Response> => {\n // 1. get session from cookie\n const sessionId = getCookie(request, this.cookieName);\n if (!sessionId) return Response.json({ data: false });\n const session = await this.repository.findById(sessionId);\n if (!session) return Response.json({ data: false });\n\n // 2. get principal name from session\n const name = session.getAttribute(PRINCIPAL_NAME_INDEX_NAME);\n session.setLastAccessedTime(Date.now());\n await this.repository.save(session);\n\n // 3. call onLogged\n if (name !== null) await onLogged?.({ name: String(name) });\n\n // 4. renew cookie\n const response = Response.json({ data: name !== null });\n const maxAge = session.getMaxInactiveInterval();\n setCookie(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });\n\n return response;\n };\n\n oauth2Authorization = async (request: Request): Promise<Response> => {\n invariant(this.oauth2Client, 'oauth2Client is not initialized');\n const { registrationId } = param(request, this.PATH_OAUTH2_AUTHORIZATION);\n const state = randomUUID();\n const codeVerifier = randomUUID();\n const uri = this.oauth2Client.createAuthorizationUri(registrationId, state, codeVerifier);\n const sessionId = getCookie(request, this.cookieName);\n const session = sessionId\n ? ((await this.repository.findById(sessionId)) ?? this.repository.createSession())\n : this.repository.createSession();\n\n const authorizationRequest: OAuth2AuthorizationRequest = {\n state,\n codeVerifier,\n registrationId,\n authorizationRequestUri: uri.href,\n };\n\n const value = JSON.stringify(authorizationRequest);\n session.setAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST, value);\n await this.repository.save(session);\n\n const response = Response.redirect(uri.href, 302);\n const maxAge = session.getMaxInactiveInterval();\n setCookie(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });\n return response;\n };\n\n private redirect = (error: string): Response => {\n invariant(this.oauth2Client, 'oauth2Client is not initialized');\n return Response.redirect(`${this.oauth2Client.errorUri}?error=${error}`, 302);\n };\n\n loginOAuth2 = async (\n request: Request,\n onAuthorized: OAuth2AuthorizedHandler\n ): Promise<Response> => {\n invariant(this.oauth2Client, 'oauth2Client is not initialized');\n\n // 1. get session from cookie\n const sessionId = getCookie(request, this.cookieName);\n const session = sessionId ? await this.repository.findById(sessionId) : null;\n if (!session) {\n return this.redirect('OAUTH2_AUTHORIZATION_SESSION_NOT_FOUND');\n }\n\n // 2. get cached authorization request from session\n const json = session.getAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST) as string | null;\n if (!json) {\n return this.redirect('OAUTH2_AUTHORIZATION_REQUEST_NOT_FOUND');\n }\n const cached: OAuth2AuthorizationRequest = JSON.parse(json);\n\n // 3. validate redirect query\n const { registrationId } = param(request, this.PATH_OAUTH2_REDIRECT);\n const parsed = oauth2RedirectQuerySchema.safeParse(query(request));\n if (!parsed.success) {\n return this.redirect('INVALID_OAUTH2_REDIRECT_QUERY');\n }\n if (parsed.data.state !== cached.state) {\n return this.redirect('INVALID_OAUTH2_REDIRECT_STATE');\n }\n if (registrationId !== cached.registrationId) {\n return this.redirect('INVALID_OAUTH2_REDIRECT_REGISTRATION_ID');\n }\n\n // 4. exchange authorization code for token and get user info\n const { code } = parsed.data;\n const { codeVerifier } = cached;\n const token = await this.oauth2Client.exchangeAuthorizationCode(\n registrationId,\n code,\n codeVerifier\n );\n const userInfo = await this.oauth2Client.getUserInfo(registrationId, token);\n\n // 5. create or update principal\n const principal = await onAuthorized(request, registrationId, userInfo, token);\n\n // 6. update session\n session.setLastAccessedTime(Date.now());\n session.removeAttribute(this.ATTR_OAUTH2_AUTHORIZATION_REQUEST);\n session.setAttribute(PRINCIPAL_NAME_INDEX_NAME, principal.name);\n await this.repository.save(session);\n\n const response = Response.redirect(this.oauth2Client.baseUri, 302);\n const maxAge = session.getMaxInactiveInterval();\n setCookie(response, this.cookieName, session.getId(), { ...this.cookieOptions, maxAge });\n return response;\n };\n}\n"],"mappings":";AAAA,SAAS,kBAAkB;AAC3B,OAAO,eAAe;AACtB,SAAS,iCAAyD;AAClE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,cAAc,iCAAiC;AAIjD,IAAM,OAAN,MAAkC;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAED,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,cAAc;AAAA,EAEd,4BAA4B;AAAA,EAC5B,uBAAuB;AAAA,EAEvB,oCAAoC;AAAA,EAEpD,YAAY,EAAE,YAAY,QAAQ,OAAO,GAAe;AACtD,SAAK,aAAa;AAClB,UAAM,EAAE,MAAM,GAAG,cAAc,IAAI,UAAU,CAAC;AAC9C,SAAK,aAAa,QAAQ;AAC1B,SAAK,gBAAgB;AAAA,MACnB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,GAAG;AAAA,IACL;AACA,SAAK,eAAe,QAAQ,SAAS,IAAI,aAAa,OAAO,MAAM,IAAI;AAAA,EACzE;AAAA,EAEA,SAAS,OAAO,YAAwC;AACtD,UAAM,YAAY,UAAU,SAAS,KAAK,UAAU;AACpD,QAAI,UAAW,OAAM,KAAK,WAAW,WAAW,SAAS;AACzD,UAAM,WAAW,SAAS,KAAK,CAAC,CAAC;AACjC,iBAAa,UAAU,KAAK,UAAU;AACtC,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,OAAO,SAAkB,aAAgD;AAEhF,UAAM,YAAY,UAAU,SAAS,KAAK,UAAU;AACpD,QAAI,CAAC,UAAW,QAAO,SAAS,KAAK,EAAE,MAAM,MAAM,CAAC;AACpD,UAAM,UAAU,MAAM,KAAK,WAAW,SAAS,SAAS;AACxD,QAAI,CAAC,QAAS,QAAO,SAAS,KAAK,EAAE,MAAM,MAAM,CAAC;AAGlD,UAAM,OAAO,QAAQ,aAAa,yBAAyB;AAC3D,YAAQ,oBAAoB,KAAK,IAAI,CAAC;AACtC,UAAM,KAAK,WAAW,KAAK,OAAO;AAGlC,QAAI,SAAS,KAAM,OAAM,WAAW,EAAE,MAAM,OAAO,IAAI,EAAE,CAAC;AAG1D,UAAM,WAAW,SAAS,KAAK,EAAE,MAAM,SAAS,KAAK,CAAC;AACtD,UAAM,SAAS,QAAQ,uBAAuB;AAC9C,cAAU,UAAU,KAAK,YAAY,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK,eAAe,OAAO,CAAC;AAEvF,WAAO;AAAA,EACT;AAAA,EAEA,sBAAsB,OAAO,YAAwC;AACnE,cAAU,KAAK,cAAc,iCAAiC;AAC9D,UAAM,EAAE,eAAe,IAAI,MAAM,SAAS,KAAK,yBAAyB;AACxE,UAAM,QAAQ,WAAW;AACzB,UAAM,eAAe,WAAW;AAChC,UAAM,MAAM,KAAK,aAAa,uBAAuB,gBAAgB,OAAO,YAAY;AACxF,UAAM,YAAY,UAAU,SAAS,KAAK,UAAU;AACpD,UAAM,UAAU,YACV,MAAM,KAAK,WAAW,SAAS,SAAS,KAAM,KAAK,WAAW,cAAc,IAC9E,KAAK,WAAW,cAAc;AAElC,UAAM,uBAAmD;AAAA,MACvD;AAAA,MACA;AAAA,MACA;AAAA,MACA,yBAAyB,IAAI;AAAA,IAC/B;AAEA,UAAM,QAAQ,KAAK,UAAU,oBAAoB;AACjD,YAAQ,aAAa,KAAK,mCAAmC,KAAK;AAClE,UAAM,KAAK,WAAW,KAAK,OAAO;AAElC,UAAM,WAAW,SAAS,SAAS,IAAI,MAAM,GAAG;AAChD,UAAM,SAAS,QAAQ,uBAAuB;AAC9C,cAAU,UAAU,KAAK,YAAY,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK,eAAe,OAAO,CAAC;AACvF,WAAO;AAAA,EACT;AAAA,EAEQ,WAAW,CAAC,UAA4B;AAC9C,cAAU,KAAK,cAAc,iCAAiC;AAC9D,WAAO,SAAS,SAAS,GAAG,KAAK,aAAa,QAAQ,UAAU,KAAK,IAAI,GAAG;AAAA,EAC9E;AAAA,EAEA,cAAc,OACZ,SACA,iBACsB;AACtB,cAAU,KAAK,cAAc,iCAAiC;AAG9D,UAAM,YAAY,UAAU,SAAS,KAAK,UAAU;AACpD,UAAM,UAAU,YAAY,MAAM,KAAK,WAAW,SAAS,SAAS,IAAI;AACxE,QAAI,CAAC,SAAS;AACZ,aAAO,KAAK,SAAS,wCAAwC;AAAA,IAC/D;AAGA,UAAM,OAAO,QAAQ,aAAa,KAAK,iCAAiC;AACxE,QAAI,CAAC,MAAM;AACT,aAAO,KAAK,SAAS,wCAAwC;AAAA,IAC/D;AACA,UAAM,SAAqC,KAAK,MAAM,IAAI;AAG1D,UAAM,EAAE,eAAe,IAAI,MAAM,SAAS,KAAK,oBAAoB;AACnE,UAAM,SAAS,0BAA0B,UAAU,MAAM,OAAO,CAAC;AACjE,QAAI,CAAC,OAAO,SAAS;AACnB,aAAO,KAAK,SAAS,+BAA+B;AAAA,IACtD;AACA,QAAI,OAAO,KAAK,UAAU,OAAO,OAAO;AACtC,aAAO,KAAK,SAAS,+BAA+B;AAAA,IACtD;AACA,QAAI,mBAAmB,OAAO,gBAAgB;AAC5C,aAAO,KAAK,SAAS,yCAAyC;AAAA,IAChE;AAGA,UAAM,EAAE,KAAK,IAAI,OAAO;AACxB,UAAM,EAAE,aAAa,IAAI;AACzB,UAAM,QAAQ,MAAM,KAAK,aAAa;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,WAAW,MAAM,KAAK,aAAa,YAAY,gBAAgB,KAAK;AAG1E,UAAM,YAAY,MAAM,aAAa,SAAS,gBAAgB,UAAU,KAAK;AAG7E,YAAQ,oBAAoB,KAAK,IAAI,CAAC;AACtC,YAAQ,gBAAgB,KAAK,iCAAiC;AAC9D,YAAQ,aAAa,2BAA2B,UAAU,IAAI;AAC9D,UAAM,KAAK,WAAW,KAAK,OAAO;AAElC,UAAM,WAAW,SAAS,SAAS,KAAK,aAAa,SAAS,GAAG;AACjE,UAAM,SAAS,QAAQ,uBAAuB;AAC9C,cAAU,UAAU,KAAK,YAAY,QAAQ,MAAM,GAAG,EAAE,GAAG,KAAK,eAAe,OAAO,CAAC;AACvF,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/auth/types.ts
17
+ var types_exports = {};
18
+ module.exports = __toCommonJS(types_exports);
19
+ //# sourceMappingURL=types.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/auth/types.ts"],"sourcesContent":["import { Principal } from '../core';\nimport { OAuth2ClientConfig, UserInfo } from '../oauth2/types';\nimport { OAuth2Token } from '../oauth2/types';\nimport { SessionRepository } from '../session';\nimport { CookieOptions } from '../utils/http';\n\nexport type LoggedHandler = (principal: Principal) => Promise<void>;\nexport type OAuth2AuthorizedHandler = (\n request: Request,\n registrationId: string,\n userInfo: UserInfo,\n token: OAuth2Token\n) => Promise<Principal>;\n\nexport interface AuthConfig {\n repository: SessionRepository;\n cookie?: CookieOptions & { name?: string };\n oauth2?: {\n client?: OAuth2ClientConfig;\n };\n}\n\nexport interface AuthService {\n logout: (request: Request) => Promise<Response>;\n logged: (request: Request, onLogged?: LoggedHandler) => Promise<Response>;\n\n oauth2Authorization: (request: Request) => Promise<Response>;\n loginOAuth2: (request: Request, onAuthorized: OAuth2AuthorizedHandler) => Promise<Response>;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1,25 @@
1
+ import { Principal } from '../core/index.cjs';
2
+ import { UserInfo, OAuth2Token, OAuth2ClientConfig } from '../oauth2/types.cjs';
3
+ import { SessionRepository } from '../session/types.cjs';
4
+ import { CookieOptions } from '../utils/http.cjs';
5
+ import 'cookie';
6
+
7
+ type LoggedHandler = (principal: Principal) => Promise<void>;
8
+ type OAuth2AuthorizedHandler = (request: Request, registrationId: string, userInfo: UserInfo, token: OAuth2Token) => Promise<Principal>;
9
+ interface AuthConfig {
10
+ repository: SessionRepository;
11
+ cookie?: CookieOptions & {
12
+ name?: string;
13
+ };
14
+ oauth2?: {
15
+ client?: OAuth2ClientConfig;
16
+ };
17
+ }
18
+ interface AuthService {
19
+ logout: (request: Request) => Promise<Response>;
20
+ logged: (request: Request, onLogged?: LoggedHandler) => Promise<Response>;
21
+ oauth2Authorization: (request: Request) => Promise<Response>;
22
+ loginOAuth2: (request: Request, onAuthorized: OAuth2AuthorizedHandler) => Promise<Response>;
23
+ }
24
+
25
+ export type { AuthConfig, AuthService, LoggedHandler, OAuth2AuthorizedHandler };
@@ -0,0 +1,25 @@
1
+ import { Principal } from '../core/index.js';
2
+ import { UserInfo, OAuth2Token, OAuth2ClientConfig } from '../oauth2/types.js';
3
+ import { SessionRepository } from '../session/types.js';
4
+ import { CookieOptions } from '../utils/http.js';
5
+ import 'cookie';
6
+
7
+ type LoggedHandler = (principal: Principal) => Promise<void>;
8
+ type OAuth2AuthorizedHandler = (request: Request, registrationId: string, userInfo: UserInfo, token: OAuth2Token) => Promise<Principal>;
9
+ interface AuthConfig {
10
+ repository: SessionRepository;
11
+ cookie?: CookieOptions & {
12
+ name?: string;
13
+ };
14
+ oauth2?: {
15
+ client?: OAuth2ClientConfig;
16
+ };
17
+ }
18
+ interface AuthService {
19
+ logout: (request: Request) => Promise<Response>;
20
+ logged: (request: Request, onLogged?: LoggedHandler) => Promise<Response>;
21
+ oauth2Authorization: (request: Request) => Promise<Response>;
22
+ loginOAuth2: (request: Request, onAuthorized: OAuth2AuthorizedHandler) => Promise<Response>;
23
+ }
24
+
25
+ export type { AuthConfig, AuthService, LoggedHandler, OAuth2AuthorizedHandler };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=types.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __copyProps = (to, from, except, desc) => {
7
+ if (from && typeof from === "object" || typeof from === "function") {
8
+ for (let key of __getOwnPropNames(from))
9
+ if (!__hasOwnProp.call(to, key) && key !== except)
10
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
11
+ }
12
+ return to;
13
+ };
14
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
15
+
16
+ // src/core/index.ts
17
+ var core_exports = {};
18
+ module.exports = __toCommonJS(core_exports);
19
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/core/index.ts"],"sourcesContent":["export type JSONValue =\n | null\n | string\n | number\n | boolean\n | { [value: string]: JSONValue }\n | Array<JSONValue>;\n\nexport interface Principal {\n name: string;\n}\n\nexport interface Authentication extends Principal {\n authorities: string[];\n authenticated: boolean;\n}\n\nexport interface CsrfToken {\n token: string;\n headerName: string;\n parameterName: string;\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -0,0 +1,17 @@
1
+ type JSONValue = null | string | number | boolean | {
2
+ [value: string]: JSONValue;
3
+ } | Array<JSONValue>;
4
+ interface Principal {
5
+ name: string;
6
+ }
7
+ interface Authentication extends Principal {
8
+ authorities: string[];
9
+ authenticated: boolean;
10
+ }
11
+ interface CsrfToken {
12
+ token: string;
13
+ headerName: string;
14
+ parameterName: string;
15
+ }
16
+
17
+ export type { Authentication, CsrfToken, JSONValue, Principal };
@@ -0,0 +1,17 @@
1
+ type JSONValue = null | string | number | boolean | {
2
+ [value: string]: JSONValue;
3
+ } | Array<JSONValue>;
4
+ interface Principal {
5
+ name: string;
6
+ }
7
+ interface Authentication extends Principal {
8
+ authorities: string[];
9
+ authenticated: boolean;
10
+ }
11
+ interface CsrfToken {
12
+ token: string;
13
+ headerName: string;
14
+ parameterName: string;
15
+ }
16
+
17
+ export type { Authentication, CsrfToken, JSONValue, Principal };
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/index.cjs ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Auth: () => import_auth.Auth,
24
+ OAuth2Client: () => import_client.OAuth2Client,
25
+ PRINCIPAL_NAME_INDEX_NAME: () => import_redis_session.PRINCIPAL_NAME_INDEX_NAME,
26
+ RedisIndexedSessionRepository: () => import_redis_session.RedisIndexedSessionRepository,
27
+ oauth2RedirectQuerySchema: () => import_client.oauth2RedirectQuerySchema
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+ var import_auth = require("./auth.cjs");
31
+ var import_client = require("./oauth2/client.cjs");
32
+ var import_redis_session = require("./session/redis-session.cjs");
33
+ // Annotate the CommonJS export names for ESM import in node:
34
+ 0 && (module.exports = {
35
+ Auth,
36
+ OAuth2Client,
37
+ PRINCIPAL_NAME_INDEX_NAME,
38
+ RedisIndexedSessionRepository,
39
+ oauth2RedirectQuerySchema
40
+ });
41
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { Auth } from './auth';\nexport { OAuth2Client, oauth2RedirectQuerySchema } from './oauth2/client';\nexport { RedisIndexedSessionRepository, PRINCIPAL_NAME_INDEX_NAME } from './session/redis-session';\n\nexport type { Namespace, SessionRepository } from './session/types';\nexport type { StandardClaims, OAuth2Token, UserInfo } from './oauth2/types';\nexport type { Principal } from './core/index';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAAqB;AACrB,oBAAwD;AACxD,2BAAyE;","names":[]}
@@ -0,0 +1,11 @@
1
+ export { Auth } from './auth/index.cjs';
2
+ export { OAuth2Client, oauth2RedirectQuerySchema } from './oauth2/client.cjs';
3
+ export { PRINCIPAL_NAME_INDEX_NAME, RedisIndexedSessionRepository } from './session/redis-session.cjs';
4
+ export { Namespace, SessionRepository } from './session/types.cjs';
5
+ export { OAuth2Token, StandardClaims, UserInfo } from './oauth2/types.cjs';
6
+ export { Principal } from './core/index.cjs';
7
+ import './auth/types.cjs';
8
+ import './utils/http.cjs';
9
+ import 'cookie';
10
+ import 'zod';
11
+ import 'ioredis';
@@ -0,0 +1,11 @@
1
+ export { Auth } from './auth/index.js';
2
+ export { OAuth2Client, oauth2RedirectQuerySchema } from './oauth2/client.js';
3
+ export { PRINCIPAL_NAME_INDEX_NAME, RedisIndexedSessionRepository } from './session/redis-session.js';
4
+ export { Namespace, SessionRepository } from './session/types.js';
5
+ export { OAuth2Token, StandardClaims, UserInfo } from './oauth2/types.js';
6
+ export { Principal } from './core/index.js';
7
+ import './auth/types.js';
8
+ import './utils/http.js';
9
+ import 'cookie';
10
+ import 'zod';
11
+ import 'ioredis';
package/dist/index.mjs ADDED
@@ -0,0 +1,12 @@
1
+ // src/index.ts
2
+ import { Auth } from "./auth.mjs";
3
+ import { OAuth2Client, oauth2RedirectQuerySchema } from "./oauth2/client.mjs";
4
+ import { RedisIndexedSessionRepository, PRINCIPAL_NAME_INDEX_NAME } from "./session/redis-session.mjs";
5
+ export {
6
+ Auth,
7
+ OAuth2Client,
8
+ PRINCIPAL_NAME_INDEX_NAME,
9
+ RedisIndexedSessionRepository,
10
+ oauth2RedirectQuerySchema
11
+ };
12
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["export { Auth } from './auth';\nexport { OAuth2Client, oauth2RedirectQuerySchema } from './oauth2/client';\nexport { RedisIndexedSessionRepository, PRINCIPAL_NAME_INDEX_NAME } from './session/redis-session';\n\nexport type { Namespace, SessionRepository } from './session/types';\nexport type { StandardClaims, OAuth2Token, UserInfo } from './oauth2/types';\nexport type { Principal } from './core/index';\n"],"mappings":";AAAA,SAAS,YAAY;AACrB,SAAS,cAAc,iCAAiC;AACxD,SAAS,+BAA+B,iCAAiC;","names":[]}