@owox/idp-owox-better-auth 0.18.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.
Files changed (156) hide show
  1. package/README.md +119 -0
  2. package/dist/client/IdentityOwoxClient.d.ts +41 -0
  3. package/dist/client/IdentityOwoxClient.d.ts.map +1 -0
  4. package/dist/client/IdentityOwoxClient.js +128 -0
  5. package/dist/client/dto/authFlowDto.d.ts +27 -0
  6. package/dist/client/dto/authFlowDto.d.ts.map +1 -0
  7. package/dist/client/dto/authFlowDto.js +5 -0
  8. package/dist/client/dto/idpOwoxPayloadDto.d.ts +29 -0
  9. package/dist/client/dto/idpOwoxPayloadDto.d.ts.map +1 -0
  10. package/dist/client/dto/idpOwoxPayloadDto.js +28 -0
  11. package/dist/client/dto/index.d.ts +11 -0
  12. package/dist/client/dto/index.d.ts.map +1 -0
  13. package/dist/client/dto/index.js +10 -0
  14. package/dist/client/dto/introspectionDto.d.ts +70 -0
  15. package/dist/client/dto/introspectionDto.d.ts.map +1 -0
  16. package/dist/client/dto/introspectionDto.js +15 -0
  17. package/dist/client/dto/jwksDto.d.ts +102 -0
  18. package/dist/client/dto/jwksDto.d.ts.map +1 -0
  19. package/dist/client/dto/jwksDto.js +18 -0
  20. package/dist/client/dto/revocationDto.d.ts +11 -0
  21. package/dist/client/dto/revocationDto.d.ts.map +1 -0
  22. package/dist/client/dto/revocationDto.js +1 -0
  23. package/dist/client/dto/tokenDto.d.ts +33 -0
  24. package/dist/client/dto/tokenDto.d.ts.map +1 -0
  25. package/dist/client/dto/tokenDto.js +9 -0
  26. package/dist/client/dto/tokenType.d.ts +5 -0
  27. package/dist/client/dto/tokenType.d.ts.map +1 -0
  28. package/dist/client/dto/tokenType.js +1 -0
  29. package/dist/client/index.d.ts +6 -0
  30. package/dist/client/index.d.ts.map +1 -0
  31. package/dist/client/index.js +5 -0
  32. package/dist/config/idp-better-auth-config.d.ts +9 -0
  33. package/dist/config/idp-better-auth-config.d.ts.map +1 -0
  34. package/dist/config/idp-better-auth-config.js +101 -0
  35. package/dist/config/idp-owox-config.d.ts +195 -0
  36. package/dist/config/idp-owox-config.d.ts.map +1 -0
  37. package/dist/config/idp-owox-config.js +252 -0
  38. package/dist/config/index.d.ts +6 -0
  39. package/dist/config/index.d.ts.map +1 -0
  40. package/dist/config/index.js +5 -0
  41. package/dist/core/constants.d.ts +14 -0
  42. package/dist/core/constants.d.ts.map +1 -0
  43. package/dist/core/constants.js +13 -0
  44. package/dist/core/exceptions.d.ts +27 -0
  45. package/dist/core/exceptions.d.ts.map +1 -0
  46. package/dist/core/exceptions.js +36 -0
  47. package/dist/core/logger.d.ts +17 -0
  48. package/dist/core/logger.d.ts.map +1 -0
  49. package/dist/core/logger.js +66 -0
  50. package/dist/core/pkce.d.ts +21 -0
  51. package/dist/core/pkce.d.ts.map +1 -0
  52. package/dist/core/pkce.js +27 -0
  53. package/dist/facades/owox-token-facade.d.ts +27 -0
  54. package/dist/facades/owox-token-facade.d.ts.map +1 -0
  55. package/dist/facades/owox-token-facade.js +117 -0
  56. package/dist/index.d.ts +13 -0
  57. package/dist/index.d.ts.map +1 -0
  58. package/dist/index.js +13 -0
  59. package/dist/jwt/jwksCache.d.ts +24 -0
  60. package/dist/jwt/jwksCache.d.ts.map +1 -0
  61. package/dist/jwt/jwksCache.js +41 -0
  62. package/dist/jwt/parseToken.d.ts +15 -0
  63. package/dist/jwt/parseToken.d.ts.map +1 -0
  64. package/dist/jwt/parseToken.js +26 -0
  65. package/dist/jwt/verifyJwt.d.ts +13 -0
  66. package/dist/jwt/verifyJwt.d.ts.map +1 -0
  67. package/dist/jwt/verifyJwt.js +23 -0
  68. package/dist/mappers/client-payload-mapper.d.ts +6 -0
  69. package/dist/mappers/client-payload-mapper.d.ts.map +1 -0
  70. package/dist/mappers/client-payload-mapper.js +17 -0
  71. package/dist/mappers/user-info-payload-builder.d.ts +11 -0
  72. package/dist/mappers/user-info-payload-builder.d.ts.map +1 -0
  73. package/dist/mappers/user-info-payload-builder.js +28 -0
  74. package/dist/owox-better-auth-idp.d.ts +40 -0
  75. package/dist/owox-better-auth-idp.d.ts.map +1 -0
  76. package/dist/owox-better-auth-idp.js +239 -0
  77. package/dist/resources/templates/layouts/auth.ejs +29 -0
  78. package/dist/resources/templates/pages/sign-in.ejs +66 -0
  79. package/dist/resources/templates/pages/sign-up.ejs +65 -0
  80. package/dist/resources/templates/partials/brand-panel.ejs +24 -0
  81. package/dist/resources/templates/partials/footer.ejs +10 -0
  82. package/dist/resources/templates/partials/head.ejs +64 -0
  83. package/dist/resources/templates/partials/header.ejs +7 -0
  84. package/dist/services/auth/better-auth-session-service.d.ts +28 -0
  85. package/dist/services/auth/better-auth-session-service.d.ts.map +1 -0
  86. package/dist/services/auth/better-auth-session-service.js +121 -0
  87. package/dist/services/auth/pkce-flow-orchestrator.d.ts +33 -0
  88. package/dist/services/auth/pkce-flow-orchestrator.d.ts.map +1 -0
  89. package/dist/services/auth/pkce-flow-orchestrator.js +134 -0
  90. package/dist/services/auth/platform-auth-flow-client.d.ts +16 -0
  91. package/dist/services/auth/platform-auth-flow-client.d.ts.map +1 -0
  92. package/dist/services/auth/platform-auth-flow-client.js +32 -0
  93. package/dist/services/core/token-service.d.ts +25 -0
  94. package/dist/services/core/token-service.d.ts.map +1 -0
  95. package/dist/services/core/token-service.js +56 -0
  96. package/dist/services/core/user-context-service.d.ts +23 -0
  97. package/dist/services/core/user-context-service.d.ts.map +1 -0
  98. package/dist/services/core/user-context-service.js +54 -0
  99. package/dist/services/middleware/middleware-service.d.ts +19 -0
  100. package/dist/services/middleware/middleware-service.d.ts.map +1 -0
  101. package/dist/services/middleware/middleware-service.js +62 -0
  102. package/dist/services/middleware/request-handler-service.d.ts +18 -0
  103. package/dist/services/middleware/request-handler-service.d.ts.map +1 -0
  104. package/dist/services/middleware/request-handler-service.js +131 -0
  105. package/dist/services/rendering/page-service.d.ts +11 -0
  106. package/dist/services/rendering/page-service.d.ts.map +1 -0
  107. package/dist/services/rendering/page-service.js +26 -0
  108. package/dist/services/rendering/template-service.d.ts +17 -0
  109. package/dist/services/rendering/template-service.d.ts.map +1 -0
  110. package/dist/services/rendering/template-service.js +52 -0
  111. package/dist/social/google-provider.d.ts +35 -0
  112. package/dist/social/google-provider.d.ts.map +1 -0
  113. package/dist/social/google-provider.js +55 -0
  114. package/dist/social/social-provider.d.ts +23 -0
  115. package/dist/social/social-provider.d.ts.map +1 -0
  116. package/dist/social/social-provider.js +1 -0
  117. package/dist/store/database-store-factory.d.ts +8 -0
  118. package/dist/store/database-store-factory.d.ts.map +1 -0
  119. package/dist/store/database-store-factory.js +38 -0
  120. package/dist/store/database-store.d.ts +20 -0
  121. package/dist/store/database-store.d.ts.map +1 -0
  122. package/dist/store/database-store.js +1 -0
  123. package/dist/store/mysql-database-store.d.ts +40 -0
  124. package/dist/store/mysql-database-store.d.ts.map +1 -0
  125. package/dist/store/mysql-database-store.js +213 -0
  126. package/dist/store/sqlite-database-store.d.ts +32 -0
  127. package/dist/store/sqlite-database-store.d.ts.map +1 -0
  128. package/dist/store/sqlite-database-store.js +205 -0
  129. package/dist/store/store-result.d.ts +16 -0
  130. package/dist/store/store-result.d.ts.map +1 -0
  131. package/dist/store/store-result.js +25 -0
  132. package/dist/types/auth-request-context.d.ts +15 -0
  133. package/dist/types/auth-request-context.d.ts.map +1 -0
  134. package/dist/types/auth-request-context.js +12 -0
  135. package/dist/types/auth-session.d.ts +25 -0
  136. package/dist/types/auth-session.d.ts.map +1 -0
  137. package/dist/types/auth-session.js +1 -0
  138. package/dist/types/database-models.d.ts +39 -0
  139. package/dist/types/database-models.d.ts.map +1 -0
  140. package/dist/types/database-models.js +1 -0
  141. package/dist/types/index.d.ts +45 -0
  142. package/dist/types/index.d.ts.map +1 -0
  143. package/dist/types/index.js +2 -0
  144. package/dist/utils/cookie-policy.d.ts +16 -0
  145. package/dist/utils/cookie-policy.d.ts.map +1 -0
  146. package/dist/utils/cookie-policy.js +27 -0
  147. package/dist/utils/platform-redirect-builder.d.ts +29 -0
  148. package/dist/utils/platform-redirect-builder.d.ts.map +1 -0
  149. package/dist/utils/platform-redirect-builder.js +86 -0
  150. package/dist/utils/request-utils.d.ts +87 -0
  151. package/dist/utils/request-utils.d.ts.map +1 -0
  152. package/dist/utils/request-utils.js +171 -0
  153. package/dist/utils/string-utils.d.ts +13 -0
  154. package/dist/utils/string-utils.d.ts.map +1 -0
  155. package/dist/utils/string-utils.js +21 -0
  156. package/package.json +71 -0
@@ -0,0 +1,252 @@
1
+ import { parseMysqlSslEnv } from '@owox/internal-helpers';
2
+ import envPaths from 'env-paths';
3
+ import { existsSync, mkdirSync } from 'fs';
4
+ import ms from 'ms';
5
+ import { dirname, join } from 'path';
6
+ import { z } from 'zod';
7
+ const zMsString = z
8
+ .string()
9
+ .refine((s) => ms(s) !== undefined, {
10
+ message: 'Invalid duration string',
11
+ })
12
+ .transform(s => s);
13
+ function normalizeOrigin(value, label) {
14
+ try {
15
+ return new URL(value).origin;
16
+ }
17
+ catch (error) {
18
+ throw new Error(`Invalid ${label} value: ${value}. ${error instanceof Error ? error.message : error}`);
19
+ }
20
+ }
21
+ function ensureValidUrl(value) {
22
+ try {
23
+ new URL(value);
24
+ return value;
25
+ }
26
+ catch {
27
+ throw new Error(`Invalid URL: ${value}`);
28
+ }
29
+ }
30
+ function buildAllowedRedirectOrigins(raw, signInUrl, signUpUrl) {
31
+ const defaults = [
32
+ normalizeOrigin(signInUrl, 'IDP_OWOX_PLATFORM_SIGN_IN_URL'),
33
+ normalizeOrigin(signUpUrl, 'IDP_OWOX_PLATFORM_SIGN_UP_URL'),
34
+ ];
35
+ const extra = raw
36
+ ? raw
37
+ .split(',')
38
+ .map(x => x.trim())
39
+ .filter(Boolean)
40
+ .map(origin => normalizeOrigin(origin, 'IDP_OWOX_ALLOWED_REDIRECT_ORIGINS'))
41
+ : [];
42
+ return Array.from(new Set([...defaults, ...extra]));
43
+ }
44
+ /** ---------- DB env (SQLite or MySQL) ---------- */
45
+ function defaultSqlitePath() {
46
+ const paths = envPaths('owox', { suffix: '' });
47
+ const dbPath = join(paths.data, 'sqlite', 'idp-owox-better-auth.db');
48
+ const dbDir = dirname(dbPath);
49
+ if (!existsSync(dbDir)) {
50
+ try {
51
+ mkdirSync(dbDir, { recursive: true });
52
+ }
53
+ catch (error) {
54
+ throw new Error(`Failed to create SQLite database directory: ${dbDir}. ${error instanceof Error ? error.message : error}`);
55
+ }
56
+ }
57
+ return dbPath;
58
+ }
59
+ const MysqlEnvSchemaRaw = z.object({
60
+ IDP_OWOX_DB_TYPE: z.literal('mysql'),
61
+ IDP_OWOX_MYSQL_HOST: z.string().min(1, 'IDP_OWOX_MYSQL_HOST is required'),
62
+ IDP_OWOX_MYSQL_USER: z.string().min(1, 'IDP_OWOX_MYSQL_USER is required'),
63
+ IDP_OWOX_MYSQL_PASSWORD: z.string().min(1, 'IDP_OWOX_MYSQL_PASSWORD is required'),
64
+ IDP_OWOX_MYSQL_DB: z.string().min(1, 'IDP_OWOX_MYSQL_DB is required'),
65
+ IDP_OWOX_MYSQL_PORT: z.string().optional(),
66
+ IDP_OWOX_MYSQL_CONNECTION_LIMIT: z.string().optional(),
67
+ IDP_OWOX_MYSQL_SSL: z.string().optional(),
68
+ });
69
+ const SqliteEnvSchemaRaw = z.object({
70
+ IDP_OWOX_DB_TYPE: z.literal('sqlite'),
71
+ IDP_OWOX_SQLITE_DB_PATH: z.string().optional(),
72
+ });
73
+ const DbEnvSchema = z
74
+ .discriminatedUnion('IDP_OWOX_DB_TYPE', [MysqlEnvSchemaRaw, SqliteEnvSchemaRaw])
75
+ .transform(env => {
76
+ if (env.IDP_OWOX_DB_TYPE === 'mysql') {
77
+ const port = env.IDP_OWOX_MYSQL_PORT ? Number(env.IDP_OWOX_MYSQL_PORT) : undefined;
78
+ const connectionLimit = env.IDP_OWOX_MYSQL_CONNECTION_LIMIT
79
+ ? Number(env.IDP_OWOX_MYSQL_CONNECTION_LIMIT)
80
+ : undefined;
81
+ const ssl = parseMysqlSslEnv(env.IDP_OWOX_MYSQL_SSL);
82
+ return {
83
+ type: 'mysql',
84
+ host: env.IDP_OWOX_MYSQL_HOST,
85
+ port,
86
+ user: env.IDP_OWOX_MYSQL_USER,
87
+ password: env.IDP_OWOX_MYSQL_PASSWORD,
88
+ database: env.IDP_OWOX_MYSQL_DB,
89
+ connectionLimit,
90
+ ...(ssl === undefined ? {} : { ssl }),
91
+ };
92
+ }
93
+ return {
94
+ type: 'sqlite',
95
+ filename: env.IDP_OWOX_SQLITE_DB_PATH ?? defaultSqlitePath(),
96
+ };
97
+ });
98
+ export function loadDbConfigFromEnv(env = process.env) {
99
+ const IDP_OWOX_DB_TYPE = (env.IDP_OWOX_DB_TYPE ?? 'sqlite').toLowerCase();
100
+ return DbEnvSchema.parse({ ...env, IDP_OWOX_DB_TYPE });
101
+ }
102
+ /** ---------- IdentityOwox client ---------- */
103
+ const IdentityOwoxClientEnvSchema = z
104
+ .object({
105
+ IDP_OWOX_CLIENT_BASE_URL: z
106
+ .string()
107
+ .url({ message: 'IDP_OWOX_CLIENT_BASE_URL must be a valid URL' }),
108
+ IDP_OWOX_DEFAULT_HEADERS: z.string().optional(),
109
+ IDP_OWOX_TIMEOUT: zMsString.optional(),
110
+ IDP_OWOX_CLIENT_BACKCHANNEL_PREFIX: z
111
+ .string()
112
+ .min(1, 'IDP_OWOX_CLIENT_BACKCHANNEL_PREFIX is required'),
113
+ IDP_OWOX_C2C_SERVICE_ACCOUNT: z.string().min(1, 'IDP_OWOX_C2C_SERVICE_ACCOUNT is required'),
114
+ IDP_OWOX_C2C_TARGET_AUDIENCE: z.string().min(1, 'IDP_OWOX_C2C_TARGET_AUDIENCE is required'),
115
+ })
116
+ .transform(e => {
117
+ const defaultHeaders = e.IDP_OWOX_DEFAULT_HEADERS
118
+ ? JSON.parse(e.IDP_OWOX_DEFAULT_HEADERS)
119
+ : undefined;
120
+ return {
121
+ clientBaseUrl: e.IDP_OWOX_CLIENT_BASE_URL,
122
+ defaultHeaders,
123
+ clientTimeout: (e.IDP_OWOX_TIMEOUT ?? '3s'),
124
+ clientBackchannelPrefix: e.IDP_OWOX_CLIENT_BACKCHANNEL_PREFIX,
125
+ c2cServiceAccountEmail: e.IDP_OWOX_C2C_SERVICE_ACCOUNT,
126
+ c2cTargetAudience: e.IDP_OWOX_C2C_TARGET_AUDIENCE,
127
+ };
128
+ });
129
+ /** ---------- IDP (frontend/app) config ---------- */
130
+ const IdpEnvSchema = z
131
+ .object({
132
+ IDP_OWOX_CLIENT_ID: z.string().min(1, 'IDP_OWOX_CLIENT_ID is required'),
133
+ IDP_OWOX_PLATFORM_SIGN_IN_URL: z
134
+ .string()
135
+ .url({ message: 'IDP_OWOX_PLATFORM_SIGN_IN_URL must be a valid URL' }),
136
+ IDP_OWOX_PLATFORM_SIGN_UP_URL: z
137
+ .string()
138
+ .url({ message: 'IDP_OWOX_PLATFORM_SIGN_UP_URL must be a valid URL' }),
139
+ IDP_OWOX_ALLOWED_REDIRECT_ORIGINS: z.string().optional(),
140
+ IDP_OWOX_SIGN_OUT_REDIRECT_URL: z
141
+ .string()
142
+ .url({ message: 'IDP_OWOX_SIGN_OUT_REDIRECT_URL must be a valid URL' })
143
+ .optional(),
144
+ })
145
+ .transform(e => ({
146
+ clientId: e.IDP_OWOX_CLIENT_ID,
147
+ platformSignInUrl: e.IDP_OWOX_PLATFORM_SIGN_IN_URL,
148
+ platformSignUpUrl: e.IDP_OWOX_PLATFORM_SIGN_UP_URL,
149
+ signOutRedirectUrl: e.IDP_OWOX_SIGN_OUT_REDIRECT_URL,
150
+ allowedRedirectOrigins: buildAllowedRedirectOrigins(e.IDP_OWOX_ALLOWED_REDIRECT_ORIGINS, e.IDP_OWOX_PLATFORM_SIGN_IN_URL, e.IDP_OWOX_PLATFORM_SIGN_UP_URL),
151
+ }));
152
+ /** ---------- JWT config ---------- */
153
+ const JwtEnvSchema = z
154
+ .object({
155
+ IDP_OWOX_JWT_CLOCK_TOLERANCE: zMsString.default('5s'),
156
+ IDP_OWOX_JWT_ISSUER: z.string().min(1, 'IDP_OWOX_JWT_ISSUER is required'),
157
+ IDP_OWOX_JWT_CACHE_TTL: zMsString.optional(),
158
+ IDP_OWOX_JWT_ALGORITHM: z.enum(['RS256']).default('RS256'),
159
+ })
160
+ .transform(e => ({
161
+ clockTolerance: e.IDP_OWOX_JWT_CLOCK_TOLERANCE,
162
+ issuer: e.IDP_OWOX_JWT_ISSUER,
163
+ jwtKeyCacheTtl: e.IDP_OWOX_JWT_CACHE_TTL ?? '1h',
164
+ algorithm: e.IDP_OWOX_JWT_ALGORITHM,
165
+ }));
166
+ /** ---------- Better Auth (UI/auth) config ---------- */
167
+ const DEFAULT_SESSION_MAX_AGE = 60 * 30; // 30 minutes
168
+ const BetterAuthEnvSchema = z.object({
169
+ IDP_BETTER_AUTH_SECRET: z.string().min(32, 'IDP_BETTER_AUTH_SECRET is required'),
170
+ IDP_BETTER_AUTH_SESSION_MAX_AGE: z.string().optional(),
171
+ IDP_BETTER_AUTH_TRUSTED_ORIGINS: z.string().optional(),
172
+ IDP_BETTER_AUTH_GOOGLE_CLIENT_ID: z.string().optional(),
173
+ IDP_BETTER_AUTH_GOOGLE_CLIENT_SECRET: z.string().optional(),
174
+ IDP_BETTER_AUTH_GOOGLE_PROMPT: z.string().optional(),
175
+ IDP_BETTER_AUTH_GOOGLE_ACCESS_TYPE: z.string().optional(),
176
+ });
177
+ function resolveBaseUrl(env) {
178
+ const baseURL = env.PUBLIC_ORIGIN ?? (env.PORT ? `http://localhost:${env.PORT}` : '');
179
+ return ensureValidUrl(baseURL);
180
+ }
181
+ function toNumber(value, fallback) {
182
+ if (!value)
183
+ return fallback;
184
+ const parsed = Number(value);
185
+ return Number.isFinite(parsed) ? parsed : fallback;
186
+ }
187
+ function parseTrustedOrigins(raw, baseUrl) {
188
+ const origins = raw
189
+ ? raw
190
+ .split(',')
191
+ .map(x => x.trim())
192
+ .filter(Boolean)
193
+ .map(origin => normalizeOrigin(origin, 'IDP_BETTER_AUTH_TRUSTED_ORIGINS'))
194
+ : [];
195
+ if (baseUrl) {
196
+ origins.push(normalizeOrigin(baseUrl, 'IDP_BETTER_AUTH_BASE_URL'));
197
+ }
198
+ return Array.from(new Set(origins));
199
+ }
200
+ function buildSocialProviders(env, baseURL) {
201
+ const social = {};
202
+ if (env.IDP_BETTER_AUTH_GOOGLE_CLIENT_ID && env.IDP_BETTER_AUTH_GOOGLE_CLIENT_SECRET) {
203
+ social.google = {
204
+ clientId: env.IDP_BETTER_AUTH_GOOGLE_CLIENT_ID,
205
+ clientSecret: env.IDP_BETTER_AUTH_GOOGLE_CLIENT_SECRET,
206
+ redirectURI: baseURL
207
+ ? `${baseURL.replace(/\/$/, '')}/auth/better-auth/callback/google`
208
+ : undefined,
209
+ prompt: env.IDP_BETTER_AUTH_GOOGLE_PROMPT ?? 'select_account',
210
+ accessType: env.IDP_BETTER_AUTH_GOOGLE_ACCESS_TYPE ?? 'offline',
211
+ };
212
+ }
213
+ return Object.keys(social).length ? social : undefined;
214
+ }
215
+ /**
216
+ * Load the full IdpOwoxConfig from process env.
217
+ * Throws on validation errors; ensures JWT_ALGORITHM is RS256.
218
+ */
219
+ export function loadIdpOwoxConfigFromEnv(env = process.env) {
220
+ const dbConfig = loadDbConfigFromEnv(env);
221
+ const identityOwoxClientConfig = IdentityOwoxClientEnvSchema.parse(env);
222
+ const idpConfig = IdpEnvSchema.parse(env);
223
+ const jwtConfig = JwtEnvSchema.parse(env);
224
+ const baseUrl = resolveBaseUrl(env);
225
+ if (jwtConfig.algorithm !== 'RS256') {
226
+ throw new Error(`Only RS256 is supported, got: ${jwtConfig.algorithm}`);
227
+ }
228
+ return {
229
+ baseUrl,
230
+ idpConfig,
231
+ identityOwoxClientConfig,
232
+ jwtConfig,
233
+ dbConfig,
234
+ };
235
+ }
236
+ /**
237
+ * Loads Better Auth + IdP OWOX config from environment.
238
+ */
239
+ export function loadBetterAuthProviderConfigFromEnv(env = process.env) {
240
+ const idpOwox = loadIdpOwoxConfigFromEnv(env);
241
+ const baEnv = BetterAuthEnvSchema.parse(env);
242
+ const safeBaseURL = resolveBaseUrl(env);
243
+ const betterAuthConfig = {
244
+ database: idpOwox.dbConfig,
245
+ secret: baEnv.IDP_BETTER_AUTH_SECRET,
246
+ baseURL: safeBaseURL,
247
+ session: { maxAge: toNumber(baEnv.IDP_BETTER_AUTH_SESSION_MAX_AGE, DEFAULT_SESSION_MAX_AGE) },
248
+ trustedOrigins: parseTrustedOrigins(baEnv.IDP_BETTER_AUTH_TRUSTED_ORIGINS, safeBaseURL),
249
+ socialProviders: buildSocialProviders(baEnv, safeBaseURL),
250
+ };
251
+ return { betterAuth: betterAuthConfig, idpOwox };
252
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Re-exports configuration helpers and types.
3
+ */
4
+ export { createBetterAuthConfig } from './idp-better-auth-config.js';
5
+ export { loadBetterAuthProviderConfigFromEnv, loadIdpOwoxConfigFromEnv, type BetterAuthProviderConfig, type DbConfig, type IdpOwoxConfig, type MysqlConfig, type SqliteConfig, } from './idp-owox-config.js';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EACL,mCAAmC,EACnC,wBAAwB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,GAClB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Re-exports configuration helpers and types.
3
+ */
4
+ export { createBetterAuthConfig } from './idp-better-auth-config.js';
5
+ export { loadBetterAuthProviderConfigFromEnv, loadIdpOwoxConfigFromEnv, } from './idp-owox-config.js';
@@ -0,0 +1,14 @@
1
+ /** Cookie name for core refresh token. */
2
+ export declare const CORE_REFRESH_TOKEN_COOKIE = "refreshToken";
3
+ /** Cookie name for Better Auth session token. */
4
+ export declare const BETTER_AUTH_SESSION_COOKIE = "better-auth.session_token";
5
+ /** Cookie name for Better Auth CSRF token. */
6
+ export declare const BETTER_AUTH_CSRF_COOKIE = "better-auth.csrf_token";
7
+ /** Cookie name for Better Auth OAuth state. */
8
+ export declare const BETTER_AUTH_STATE_COOKIE = "better-auth.state";
9
+ /** Source parameter values used across IDP requests. */
10
+ export declare const SOURCE: {
11
+ readonly APP: "app";
12
+ readonly PLATFORM: "platform";
13
+ };
14
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/core/constants.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,eAAO,MAAM,yBAAyB,iBAAiB,CAAC;AACxD,iDAAiD;AACjD,eAAO,MAAM,0BAA0B,8BAA8B,CAAC;AACtE,8CAA8C;AAC9C,eAAO,MAAM,uBAAuB,2BAA2B,CAAC;AAChE,+CAA+C;AAC/C,eAAO,MAAM,wBAAwB,sBAAsB,CAAC;AAE5D,wDAAwD;AACxD,eAAO,MAAM,MAAM;;;CAGT,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** Cookie name for core refresh token. */
2
+ export const CORE_REFRESH_TOKEN_COOKIE = 'refreshToken';
3
+ /** Cookie name for Better Auth session token. */
4
+ export const BETTER_AUTH_SESSION_COOKIE = 'better-auth.session_token';
5
+ /** Cookie name for Better Auth CSRF token. */
6
+ export const BETTER_AUTH_CSRF_COOKIE = 'better-auth.csrf_token';
7
+ /** Cookie name for Better Auth OAuth state. */
8
+ export const BETTER_AUTH_STATE_COOKIE = 'better-auth.state';
9
+ /** Source parameter values used across IDP requests. */
10
+ export const SOURCE = {
11
+ APP: 'app',
12
+ PLATFORM: 'platform',
13
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Error for authentication flow failures with context.
3
+ */
4
+ export declare class AuthenticationException extends Error {
5
+ readonly cause?: unknown;
6
+ readonly context?: Record<string, unknown>;
7
+ constructor(message: string, opts?: {
8
+ cause?: unknown;
9
+ context?: Record<string, unknown>;
10
+ });
11
+ }
12
+ /**
13
+ * Detects "state expired" errors by a consistent marker.
14
+ */
15
+ export declare function isStateExpiredError(error: unknown): boolean;
16
+ /**
17
+ * Error for failed requests to Identity OWOX.
18
+ */
19
+ export declare class IdpFailedException extends Error {
20
+ readonly cause?: unknown;
21
+ readonly context?: Record<string, unknown>;
22
+ constructor(message: string, opts?: {
23
+ cause?: unknown;
24
+ context?: Record<string, unknown>;
25
+ });
26
+ }
27
+ //# sourceMappingURL=exceptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exceptions.d.ts","sourceRoot":"","sources":["../../src/core/exceptions.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE/B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;CAM3F;AAID;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAI3D;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAE/B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;CAM3F"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Error for authentication flow failures with context.
3
+ */
4
+ export class AuthenticationException extends Error {
5
+ cause;
6
+ context;
7
+ constructor(message, opts) {
8
+ super(message);
9
+ this.name = 'AuthenticationException';
10
+ this.cause = opts?.cause;
11
+ this.context = opts?.context;
12
+ }
13
+ }
14
+ const STATE_EXPIRED_ERROR_MARKER = 'state expired';
15
+ /**
16
+ * Detects "state expired" errors by a consistent marker.
17
+ */
18
+ export function isStateExpiredError(error) {
19
+ if (!error || typeof error !== 'object')
20
+ return false;
21
+ const message = error instanceof Error ? error.message : String(error);
22
+ return message.toLowerCase().includes(STATE_EXPIRED_ERROR_MARKER);
23
+ }
24
+ /**
25
+ * Error for failed requests to Identity OWOX.
26
+ */
27
+ export class IdpFailedException extends Error {
28
+ cause;
29
+ context;
30
+ constructor(message, opts) {
31
+ super(message);
32
+ this.name = 'IdpRequestFailedException';
33
+ this.cause = opts?.cause;
34
+ this.context = opts?.context;
35
+ }
36
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Shared logger utilities with basic redaction helpers.
3
+ */
4
+ import { type Logger } from '@owox/internal-helpers';
5
+ /**
6
+ * Logger instance for idp-owox-better-auth.
7
+ * Use Proxy to dynamically bind the logger instance to the logger methods.
8
+ */
9
+ export declare const logger: Logger;
10
+ /**
11
+ * Console logging with light redaction to avoid leaking tokens/PII.
12
+ * Keeps console.log available for temporary tracing while protecting secrets.
13
+ *
14
+ * TODO: DELETE THIS FUNCTION AFTER DEBUGGING
15
+ */
16
+ export declare function safeConsoleLog(message: string, payload?: unknown): void;
17
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/core/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAiB,KAAK,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAWpE;;;GAGG;AACH,eAAO,MAAM,MAAM,QAWjB,CAAC;AA6BH;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,CAUvE"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Shared logger utilities with basic redaction helpers.
3
+ */
4
+ import { LoggerFactory } from '@owox/internal-helpers';
5
+ let _logger;
6
+ function getLogger() {
7
+ if (!_logger) {
8
+ _logger = LoggerFactory.createNamedLogger('idp-owox-better-auth');
9
+ }
10
+ return _logger;
11
+ }
12
+ /**
13
+ * Logger instance for idp-owox-better-auth.
14
+ * Use Proxy to dynamically bind the logger instance to the logger methods.
15
+ */
16
+ export const logger = new Proxy({}, {
17
+ get(_target, prop) {
18
+ const loggerInstance = getLogger();
19
+ const value = loggerInstance[prop];
20
+ if (typeof value === 'function') {
21
+ return value.bind(loggerInstance);
22
+ }
23
+ return value;
24
+ },
25
+ });
26
+ const SENSITIVE_KEYS = [
27
+ 'token',
28
+ 'refreshToken',
29
+ 'accessToken',
30
+ 'authorization',
31
+ 'state',
32
+ 'code',
33
+ 'cookie',
34
+ 'csrf',
35
+ 'session',
36
+ ];
37
+ function redactValue(value) {
38
+ if (typeof value === 'string') {
39
+ if (value.length <= 8)
40
+ return value;
41
+ return `${value.slice(0, 4)}...[redacted]...${value.slice(-4)}`;
42
+ }
43
+ return value;
44
+ }
45
+ function redactingReplacer(key, value) {
46
+ if (SENSITIVE_KEYS.some(k => key.toLowerCase().includes(k.toLowerCase()))) {
47
+ return redactValue(value);
48
+ }
49
+ return value;
50
+ }
51
+ /**
52
+ * Console logging with light redaction to avoid leaking tokens/PII.
53
+ * Keeps console.log available for temporary tracing while protecting secrets.
54
+ *
55
+ * TODO: DELETE THIS FUNCTION AFTER DEBUGGING
56
+ */
57
+ export function safeConsoleLog(message, payload) {
58
+ if (payload === undefined) {
59
+ // eslint-disable-next-line no-console
60
+ console.log(message);
61
+ return;
62
+ }
63
+ const serialized = typeof payload === 'string' ? payload : JSON.stringify(payload, redactingReplacer, 2);
64
+ // eslint-disable-next-line no-console
65
+ console.log(message, serialized);
66
+ }
@@ -0,0 +1,21 @@
1
+ export interface PkceDto {
2
+ codeVerifier: string;
3
+ codeChallenge: string;
4
+ }
5
+ /**
6
+ * Generates a PKCE (Proof Key for Code Exchange) pair consisting of a code verifier and a code challenge.
7
+ *
8
+ * @param {number} [length=86] - The desired length of the code verifier. Defaults to 86 if not specified.
9
+ * @return {Promise<{codeVerifier: string, codeChallenge: string}>} A promise that resolves to an object containing the code verifier and code challenge.
10
+ */
11
+ export declare function generatePkce(length?: number): Promise<PkceDto>;
12
+ /**
13
+ * Generates a random string state encoded in Base64 URL format.
14
+ * Optionally allows truncation of the generated state to a specific length.
15
+ *
16
+ * @param {number} [bytes=32] - The number of random bytes to generate.
17
+ * @param {number} [targetLen] - The desired length of the output string. If not specified, the full generated string is returned.
18
+ * @return {string} - A randomly generated Base64 URL-encoded string. If targetLen is provided, returns a substring of the specified length.
19
+ */
20
+ export declare function generateState(bytes?: number, targetLen?: number): string;
21
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/core/pkce.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,OAAO;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,MAAM,GAAE,MAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAGxE;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,GAAE,MAAW,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAG5E"}
@@ -0,0 +1,27 @@
1
+ import crypto from 'node:crypto';
2
+ import pkceChallenge from 'pkce-challenge';
3
+ /**
4
+ * Generates a PKCE (Proof Key for Code Exchange) pair consisting of a code verifier and a code challenge.
5
+ *
6
+ * @param {number} [length=86] - The desired length of the code verifier. Defaults to 86 if not specified.
7
+ * @return {Promise<{codeVerifier: string, codeChallenge: string}>} A promise that resolves to an object containing the code verifier and code challenge.
8
+ */
9
+ export async function generatePkce(length = 86) {
10
+ const { code_verifier, code_challenge } = await pkceChallenge(length);
11
+ return { codeVerifier: code_verifier, codeChallenge: code_challenge };
12
+ }
13
+ /**
14
+ * Generates a random string state encoded in Base64 URL format.
15
+ * Optionally allows truncation of the generated state to a specific length.
16
+ *
17
+ * @param {number} [bytes=32] - The number of random bytes to generate.
18
+ * @param {number} [targetLen] - The desired length of the output string. If not specified, the full generated string is returned.
19
+ * @return {string} - A randomly generated Base64 URL-encoded string. If targetLen is provided, returns a substring of the specified length.
20
+ */
21
+ export function generateState(bytes = 32, targetLen) {
22
+ const state = base64url(crypto.randomBytes(bytes));
23
+ return targetLen ? state.slice(0, targetLen) : state;
24
+ }
25
+ function base64url(buf) {
26
+ return buf.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/g, '');
27
+ }
@@ -0,0 +1,27 @@
1
+ import { AuthResult, Payload } from '@owox/idp-protocol';
2
+ import { Logger } from '@owox/internal-helpers';
3
+ import { NextFunction, Request, Response } from 'express';
4
+ import { IdentityOwoxClient, TokenResponse } from '../client/index.js';
5
+ import type { IdpOwoxConfig } from '../config/idp-owox-config.js';
6
+ import type { DatabaseStore } from '../store/database-store.js';
7
+ /**
8
+ * Wraps Identity OWOX token operations and refresh-token cookies.
9
+ */
10
+ export declare class OwoxTokenFacade {
11
+ private readonly identityClient;
12
+ private readonly store;
13
+ private readonly config;
14
+ private readonly logger;
15
+ private readonly cookieName;
16
+ private readonly tokenService;
17
+ constructor(identityClient: IdentityOwoxClient, store: DatabaseStore, config: IdpOwoxConfig, logger: Logger, cookieName?: string);
18
+ changeAuthCode(code: string, state: string): Promise<TokenResponse>;
19
+ introspectToken(token: string): Promise<Payload | null>;
20
+ parseToken(token: string): Promise<Payload | null>;
21
+ verifyToken(token: string): Promise<Payload | null>;
22
+ refreshToken(refreshToken: string): Promise<AuthResult>;
23
+ revokeToken(token: string): Promise<void>;
24
+ accessTokenMiddleware(req: Request, res: Response, _next: NextFunction): Promise<void | Response>;
25
+ setTokenToCookie(res: Response, req: Request, refreshToken: string, expiresIn: number): void;
26
+ }
27
+ //# sourceMappingURL=owox-token-facade.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owox-token-facade.d.ts","sourceRoot":"","sources":["../../src/facades/owox-token-facade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1D,OAAO,EACL,kBAAkB,EAKlB,aAAa,EACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAKlE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE;;GAEG;AACH,qBAAa,eAAe;IAIxB,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAP7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;gBAGzB,cAAc,EAAE,kBAAkB,EAClC,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,aAAa,EACrB,MAAM,EAAE,MAAM,EACd,UAAU,GAAE,MAAkC;IAW3D,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAmBnE,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAWvD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAIlD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAInD,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiBvD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC,qBAAqB,CACzB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;IA4C3B,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAOtF"}
@@ -0,0 +1,117 @@
1
+ import { CORE_REFRESH_TOKEN_COOKIE } from '../core/constants.js';
2
+ import { AuthenticationException, IdpFailedException } from '../core/exceptions.js';
3
+ import { toPayload } from '../mappers/client-payload-mapper.js';
4
+ import { TokenService } from '../services/core/token-service.js';
5
+ import { StoreReason } from '../store/store-result.js';
6
+ import { buildCookieOptions, clearCookie } from '../utils/cookie-policy.js';
7
+ /**
8
+ * Wraps Identity OWOX token operations and refresh-token cookies.
9
+ */
10
+ export class OwoxTokenFacade {
11
+ identityClient;
12
+ store;
13
+ config;
14
+ logger;
15
+ cookieName;
16
+ tokenService;
17
+ constructor(identityClient, store, config, logger, cookieName = CORE_REFRESH_TOKEN_COOKIE) {
18
+ this.identityClient = identityClient;
19
+ this.store = store;
20
+ this.config = config;
21
+ this.logger = logger;
22
+ this.cookieName = cookieName;
23
+ const tokenCfg = {
24
+ algorithm: this.config.jwtConfig.algorithm,
25
+ clockTolerance: this.config.jwtConfig.clockTolerance,
26
+ issuer: this.config.jwtConfig.issuer,
27
+ jwtKeyCacheTtl: this.config.jwtConfig.jwtKeyCacheTtl,
28
+ };
29
+ this.tokenService = new TokenService(this.identityClient, tokenCfg);
30
+ }
31
+ async changeAuthCode(code, state) {
32
+ const res = await this.store.getAuthState(state);
33
+ if (!res.code) {
34
+ if (res.reason == StoreReason.EXPIRED) {
35
+ throw new AuthenticationException('Code verifier has expired');
36
+ }
37
+ throw new IdpFailedException(`Code verifier is not available: ${res.reason ?? 'unknown'}`);
38
+ }
39
+ const request = {
40
+ grantType: 'authorization_code',
41
+ authCode: code,
42
+ codeVerifier: res.code,
43
+ clientId: this.config.idpConfig.clientId,
44
+ };
45
+ return await this.identityClient.getToken(request);
46
+ }
47
+ async introspectToken(token) {
48
+ const request = { token: token };
49
+ const response = await this.identityClient.introspectToken(request);
50
+ if (!response.isActive) {
51
+ return null;
52
+ }
53
+ return toPayload(response);
54
+ }
55
+ async parseToken(token) {
56
+ return this.tokenService.parse(token);
57
+ }
58
+ async verifyToken(token) {
59
+ return this.tokenService.verify(token);
60
+ }
61
+ async refreshToken(refreshToken) {
62
+ const request = {
63
+ grantType: 'refresh_token',
64
+ refreshToken: refreshToken,
65
+ clientId: this.config.idpConfig.clientId,
66
+ };
67
+ const response = await this.identityClient.getToken(request);
68
+ return {
69
+ accessToken: response.accessToken,
70
+ refreshToken: response.refreshToken,
71
+ accessTokenExpiresIn: response.accessTokenExpiresIn,
72
+ refreshTokenExpiresIn: response.refreshTokenExpiresIn,
73
+ };
74
+ }
75
+ async revokeToken(token) {
76
+ const request = { token: token, tokenType: 'refresh_token' };
77
+ await this.identityClient.revokeToken(request);
78
+ }
79
+ async accessTokenMiddleware(req, res, _next) {
80
+ try {
81
+ const refreshToken = req.cookies[this.cookieName];
82
+ if (!refreshToken) {
83
+ return res.json({ reason: 'atm1' });
84
+ }
85
+ const auth = await this.refreshToken(refreshToken);
86
+ const newRefreshToken = auth.refreshToken;
87
+ if (!newRefreshToken) {
88
+ return res.json({ reason: 'atm2' });
89
+ }
90
+ if (!auth.refreshTokenExpiresIn) {
91
+ return res.json({ reason: 'atm3' });
92
+ }
93
+ this.setTokenToCookie(res, req, newRefreshToken, auth.refreshTokenExpiresIn);
94
+ return res.json(auth);
95
+ }
96
+ catch (error) {
97
+ clearCookie(res, this.cookieName, req);
98
+ if (error instanceof AuthenticationException) {
99
+ this.logger.info(this.tokenService.formatError(error), {
100
+ context: error.name,
101
+ params: error.context,
102
+ cause: error.cause,
103
+ });
104
+ return res.json({ reason: 'atm4' });
105
+ }
106
+ if (error instanceof IdpFailedException) {
107
+ this.logger.error('Access Token middleware failed with unexpected code', error.context, error.cause);
108
+ return res.json({ reason: 'atm5' });
109
+ }
110
+ this.logger.error(this.tokenService.formatError(error));
111
+ return res.json({ reason: 'atm6' });
112
+ }
113
+ }
114
+ setTokenToCookie(res, req, refreshToken, expiresIn) {
115
+ res.cookie(this.cookieName, refreshToken, buildCookieOptions(req, { maxAgeMs: expiresIn * 1000 }));
116
+ }
117
+ }