nexus-shared 1.1.20 → 2.0.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 (332) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +903 -0
  3. package/dist/Client.Index.d.ts +44 -0
  4. package/dist/Client.Index.js +49 -0
  5. package/dist/Components/Documents/Button.d.ts +29 -0
  6. package/dist/Components/Documents/Button.js +11 -0
  7. package/dist/Components/Documents/Menu.d.ts +102 -0
  8. package/dist/Components/Documents/Menu.js +238 -0
  9. package/dist/Components/Documents/SplitButton.d.ts +64 -0
  10. package/dist/Components/Documents/SplitButton.js +127 -0
  11. package/dist/Components/Documents/TabButtons.d.ts +62 -0
  12. package/dist/Components/Documents/TabButtons.js +19 -0
  13. package/dist/Components/Forms/ApiForm.d.ts +21 -0
  14. package/dist/Components/Forms/ApiForm.js +99 -0
  15. package/dist/Components/Forms/Crud.d.ts +17 -0
  16. package/dist/Components/Forms/Crud.js +556 -0
  17. package/dist/Components/Forms/CrudParts.d.ts +15 -0
  18. package/dist/Components/Forms/CrudParts.js +36 -0
  19. package/dist/Components/Forms/Form.d.ts +52 -0
  20. package/dist/Components/Forms/Form.js +319 -0
  21. package/dist/Components/Forms/SubmitForm.d.ts +65 -0
  22. package/dist/Components/Forms/SubmitForm.js +198 -0
  23. package/dist/Components/Inputs/Calendar.d.ts +69 -0
  24. package/dist/Components/Inputs/Calendar.js +258 -0
  25. package/dist/Components/Inputs/CheckBox.d.ts +53 -0
  26. package/dist/Components/Inputs/CheckBox.js +87 -0
  27. package/dist/Components/Inputs/CheckBoxGroup.d.ts +20 -0
  28. package/dist/Components/Inputs/CheckBoxGroup.js +80 -0
  29. package/dist/Components/Inputs/ChoiceField.d.ts +122 -0
  30. package/dist/Components/Inputs/ChoiceField.js +169 -0
  31. package/dist/Components/Inputs/DatePicker.d.ts +54 -0
  32. package/dist/Components/Inputs/DatePicker.js +246 -0
  33. package/dist/Components/Inputs/DateRangePicker.d.ts +62 -0
  34. package/dist/Components/Inputs/DateRangePicker.js +283 -0
  35. package/dist/Components/Inputs/DateTimePicker.d.ts +75 -0
  36. package/dist/Components/Inputs/DateTimePicker.js +399 -0
  37. package/dist/Components/Inputs/Dropdown.d.ts +117 -0
  38. package/dist/Components/Inputs/Dropdown.js +839 -0
  39. package/dist/Components/Inputs/DropdownParts.d.ts +84 -0
  40. package/dist/Components/Inputs/DropdownParts.js +102 -0
  41. package/dist/Components/Inputs/EditorShell.d.ts +45 -0
  42. package/dist/Components/Inputs/EditorShell.js +214 -0
  43. package/dist/Components/Inputs/Field.d.ts +53 -0
  44. package/dist/Components/Inputs/Field.js +16 -0
  45. package/dist/Components/Inputs/GroupForm.d.ts +20 -0
  46. package/dist/Components/Inputs/GroupForm.js +170 -0
  47. package/dist/Components/Inputs/InputField.d.ts +59 -0
  48. package/dist/Components/Inputs/InputField.js +169 -0
  49. package/dist/Components/Inputs/InputRenderer.d.ts +35 -0
  50. package/dist/Components/Inputs/InputRenderer.js +99 -0
  51. package/dist/Components/Inputs/MarkdownEditor.d.ts +67 -0
  52. package/dist/Components/Inputs/MarkdownEditor.js +289 -0
  53. package/dist/Components/Inputs/NumberBox.d.ts +53 -0
  54. package/dist/Components/Inputs/NumberBox.js +228 -0
  55. package/dist/Components/Inputs/RadioGroup.d.ts +20 -0
  56. package/dist/Components/Inputs/RadioGroup.js +43 -0
  57. package/dist/Components/Inputs/ReadOnlyNotice.d.ts +36 -0
  58. package/dist/Components/Inputs/ReadOnlyNotice.js +116 -0
  59. package/dist/Components/Inputs/RichTextEditor.d.ts +103 -0
  60. package/dist/Components/Inputs/RichTextEditor.js +1170 -0
  61. package/dist/Components/Inputs/RichTextParts.d.ts +63 -0
  62. package/dist/Components/Inputs/RichTextParts.js +157 -0
  63. package/dist/Components/Inputs/RowsInput.d.ts +104 -0
  64. package/dist/Components/Inputs/RowsInput.js +259 -0
  65. package/dist/Components/Inputs/Slider.d.ts +87 -0
  66. package/dist/Components/Inputs/Slider.js +216 -0
  67. package/dist/Components/Inputs/TabularForm.d.ts +23 -0
  68. package/dist/Components/Inputs/TabularForm.js +283 -0
  69. package/dist/Components/Inputs/TextArea.d.ts +43 -0
  70. package/dist/Components/Inputs/TextArea.js +31 -0
  71. package/dist/Components/Inputs/TextBox.d.ts +52 -0
  72. package/dist/Components/Inputs/TextBox.js +58 -0
  73. package/dist/Components/Inputs/TextField.d.ts +31 -0
  74. package/dist/Components/Inputs/TextField.js +35 -0
  75. package/dist/Components/Inputs/TimePanel.d.ts +34 -0
  76. package/dist/Components/Inputs/TimePanel.js +288 -0
  77. package/dist/Components/Inputs/TimePicker.d.ts +54 -0
  78. package/dist/Components/Inputs/TimePicker.js +239 -0
  79. package/dist/Components/Inputs/TreeView.d.ts +160 -0
  80. package/dist/Components/Inputs/TreeView.js +947 -0
  81. package/dist/Components/Layouts/MessageBox.d.ts +71 -0
  82. package/dist/Components/Layouts/MessageBox.js +104 -0
  83. package/dist/Components/Layouts/Popup.d.ts +92 -0
  84. package/dist/Components/Layouts/Popup.js +376 -0
  85. package/dist/Components/Layouts/PopupContext.d.ts +2 -0
  86. package/dist/Components/Layouts/PopupContext.js +4 -0
  87. package/dist/Components/Layouts/PopupDock.d.ts +22 -0
  88. package/dist/Components/Layouts/PopupDock.js +121 -0
  89. package/dist/Components/Layouts/PopupHost.d.ts +56 -0
  90. package/dist/Components/Layouts/PopupHost.js +163 -0
  91. package/dist/Components/Layouts/PopupRules.d.ts +30 -0
  92. package/dist/Components/Layouts/PopupRules.js +63 -0
  93. package/dist/Components/Layouts/ThemePicker.d.ts +13 -0
  94. package/dist/Components/Layouts/ThemePicker.js +22 -0
  95. package/dist/Components/Layouts/ThemeScript.d.ts +14 -0
  96. package/dist/Components/Layouts/ThemeScript.js +13 -0
  97. package/dist/Components/Layouts/ThemeSwitcher.d.ts +13 -0
  98. package/dist/Components/Layouts/ThemeSwitcher.js +29 -0
  99. package/dist/Components/Layouts/Toaster.d.ts +76 -0
  100. package/dist/Components/Layouts/Toaster.js +172 -0
  101. package/dist/Components/Viewers/DataTable.d.ts +25 -0
  102. package/dist/Components/Viewers/DataTable.js +542 -0
  103. package/dist/Components/Viewers/DataTableParts.d.ts +134 -0
  104. package/dist/Components/Viewers/DataTableParts.js +145 -0
  105. package/dist/Components/Viewers/MarkdownView.d.ts +26 -0
  106. package/dist/Components/Viewers/MarkdownView.js +79 -0
  107. package/dist/Components/Viewers/RichTextView.d.ts +18 -0
  108. package/dist/Components/Viewers/RichTextView.js +17 -0
  109. package/dist/Helpers/AnimationHelpers.d.ts +6 -0
  110. package/dist/Helpers/AnimationHelpers.js +35 -0
  111. package/dist/Helpers/ApiClient.d.ts +74 -0
  112. package/dist/Helpers/ApiClient.js +197 -0
  113. package/dist/Helpers/ApiFormHelpers.d.ts +26 -0
  114. package/dist/Helpers/ApiFormHelpers.js +56 -0
  115. package/dist/Helpers/ApiModules.d.ts +135 -0
  116. package/dist/Helpers/ApiModules.js +194 -0
  117. package/dist/Helpers/ApiResponses.d.ts +41 -0
  118. package/dist/Helpers/ApiResponses.js +159 -0
  119. package/dist/Helpers/ApiRoutes.d.ts +150 -0
  120. package/dist/Helpers/ApiRoutes.js +191 -0
  121. package/dist/Helpers/ApiToasts.d.ts +21 -0
  122. package/dist/Helpers/ApiToasts.js +22 -0
  123. package/dist/Helpers/ClassHelpers.d.ts +3 -0
  124. package/dist/Helpers/ClassHelpers.js +4 -0
  125. package/dist/Helpers/CrudBackend.d.ts +56 -0
  126. package/dist/Helpers/CrudBackend.js +119 -0
  127. package/dist/Helpers/CrudHelpers.d.ts +76 -0
  128. package/dist/Helpers/CrudHelpers.js +202 -0
  129. package/dist/Helpers/DateHelpers.d.ts +88 -0
  130. package/dist/Helpers/DateHelpers.js +363 -0
  131. package/dist/Helpers/DatePreferences.d.ts +14 -0
  132. package/dist/Helpers/DatePreferences.js +94 -0
  133. package/dist/Helpers/DateTimeHelpers.d.ts +87 -0
  134. package/dist/Helpers/DateTimeHelpers.js +286 -0
  135. package/dist/Helpers/DragHelpers.d.ts +129 -0
  136. package/dist/Helpers/DragHelpers.js +281 -0
  137. package/dist/Helpers/DropdownHelpers.d.ts +56 -0
  138. package/dist/Helpers/DropdownHelpers.js +180 -0
  139. package/dist/Helpers/FormDrafts.d.ts +18 -0
  140. package/dist/Helpers/FormDrafts.js +76 -0
  141. package/dist/Helpers/FormStore.d.ts +231 -0
  142. package/dist/Helpers/FormStore.js +734 -0
  143. package/dist/Helpers/InputParamsHelpers.d.ts +79 -0
  144. package/dist/Helpers/InputParamsHelpers.js +388 -0
  145. package/dist/Helpers/MarkdownEditing.d.ts +27 -0
  146. package/dist/Helpers/MarkdownEditing.js +250 -0
  147. package/dist/Helpers/MarkdownHelpers.d.ts +82 -0
  148. package/dist/Helpers/MarkdownHelpers.js +775 -0
  149. package/dist/Helpers/MessageBuilder.d.ts +74 -0
  150. package/dist/Helpers/MessageBuilder.js +254 -0
  151. package/dist/Helpers/NepaliCalendar.d.ts +25 -0
  152. package/dist/Helpers/NepaliCalendar.js +107 -0
  153. package/dist/Helpers/NumberHelpers.d.ts +71 -0
  154. package/dist/Helpers/NumberHelpers.js +202 -0
  155. package/dist/Helpers/Permissions.d.ts +62 -0
  156. package/dist/Helpers/Permissions.js +133 -0
  157. package/dist/Helpers/PopoverHelpers.d.ts +43 -0
  158. package/dist/Helpers/PopoverHelpers.js +91 -0
  159. package/dist/Helpers/RichTextHelpers.d.ts +77 -0
  160. package/dist/Helpers/RichTextHelpers.js +1072 -0
  161. package/dist/Helpers/RowsStore.d.ts +160 -0
  162. package/dist/Helpers/RowsStore.js +584 -0
  163. package/dist/Helpers/TableColumns.d.ts +40 -0
  164. package/dist/Helpers/TableColumns.js +254 -0
  165. package/dist/Helpers/TableExport.d.ts +30 -0
  166. package/dist/Helpers/TableExport.js +97 -0
  167. package/dist/Helpers/TableHelpers.d.ts +102 -0
  168. package/dist/Helpers/TableHelpers.js +281 -0
  169. package/dist/Helpers/TableStore.d.ts +142 -0
  170. package/dist/Helpers/TableStore.js +530 -0
  171. package/dist/Helpers/ThemeHelpers.d.ts +15 -0
  172. package/dist/Helpers/ThemeHelpers.js +16 -0
  173. package/dist/Helpers/TimeHelpers.d.ts +73 -0
  174. package/dist/Helpers/TimeHelpers.js +253 -0
  175. package/dist/Helpers/TreeStore.d.ts +188 -0
  176. package/dist/Helpers/TreeStore.js +577 -0
  177. package/dist/Helpers/ValidationHelpers.d.ts +124 -0
  178. package/dist/Helpers/ValidationHelpers.js +301 -0
  179. package/dist/Interfaces/ApiInterfaces.d.ts +149 -0
  180. package/dist/Interfaces/ApiInterfaces.js +24 -0
  181. package/dist/Interfaces/CrudInterfaces.d.ts +171 -0
  182. package/{src/sso-client.tsx → dist/Interfaces/CrudInterfaces.js} +1 -1
  183. package/dist/Interfaces/DateInterfaces.d.ts +154 -0
  184. package/dist/Interfaces/DateInterfaces.js +29 -0
  185. package/dist/Interfaces/FormInterfaces.d.ts +352 -0
  186. package/dist/Interfaces/FormInterfaces.js +1 -0
  187. package/dist/Interfaces/InputInterfaces.d.ts +141 -0
  188. package/dist/Interfaces/InputInterfaces.js +1 -0
  189. package/dist/Interfaces/MessageInterfaces.d.ts +111 -0
  190. package/dist/Interfaces/MessageInterfaces.js +5 -0
  191. package/dist/Interfaces/TableInterfaces.d.ts +291 -0
  192. package/dist/Interfaces/TableInterfaces.js +1 -0
  193. package/dist/Interfaces/ThemeInterfaces.d.ts +17 -0
  194. package/dist/Interfaces/ThemeInterfaces.js +17 -0
  195. package/dist/Interfaces/TypeInterfaces.d.ts +4 -0
  196. package/dist/Interfaces/TypeInterfaces.js +1 -0
  197. package/dist/Server.Index.d.ts +2 -0
  198. package/dist/Server.Index.js +5 -0
  199. package/dist/Services/ApiProxy.d.ts +32 -0
  200. package/dist/Services/ApiProxy.js +111 -0
  201. package/dist/Services/BrowserApi.d.ts +78 -0
  202. package/dist/Services/BrowserApi.js +111 -0
  203. package/dist/Services/ServerApi.d.ts +49 -0
  204. package/dist/Services/ServerApi.js +75 -0
  205. package/dist/Services/ThemeService.d.ts +17 -0
  206. package/dist/Services/ThemeService.js +83 -0
  207. package/dist/Shared.Index.d.ts +43 -0
  208. package/dist/Shared.Index.js +47 -0
  209. package/package.json +82 -33
  210. package/src/Styles/Nexus.Base.css +70 -0
  211. package/src/Styles/Nexus.Button.css +151 -0
  212. package/src/Styles/Nexus.Calendar.css +275 -0
  213. package/src/Styles/Nexus.Choice.css +345 -0
  214. package/src/Styles/Nexus.Crud.css +84 -0
  215. package/src/Styles/Nexus.DateTime.css +81 -0
  216. package/src/Styles/Nexus.Dropdown.css +774 -0
  217. package/src/Styles/Nexus.Editor.css +297 -0
  218. package/src/Styles/Nexus.Form.css +298 -0
  219. package/src/Styles/Nexus.Index.css +34 -0
  220. package/src/Styles/Nexus.Input.css +637 -0
  221. package/src/Styles/Nexus.Markdown.css +265 -0
  222. package/src/Styles/Nexus.Menu.css +249 -0
  223. package/src/Styles/Nexus.Popup.css +731 -0
  224. package/src/Styles/Nexus.RichText.css +463 -0
  225. package/src/Styles/Nexus.Rows.css +566 -0
  226. package/src/Styles/Nexus.Slider.css +278 -0
  227. package/src/Styles/Nexus.Tab.Buttons.css +364 -0
  228. package/src/Styles/Nexus.Table.css +1014 -0
  229. package/src/Styles/Nexus.Theme.Picker.css +159 -0
  230. package/src/Styles/Nexus.Themes.css +194 -0
  231. package/src/Styles/Nexus.Time.css +147 -0
  232. package/src/Styles/Nexus.Toast.css +265 -0
  233. package/src/Styles/Nexus.Tokens.css +72 -0
  234. package/src/Styles/Nexus.Tree.css +435 -0
  235. package/src/api-services/authentication-service.tsx +0 -23
  236. package/src/api-services/preference-service.tsx +0 -5
  237. package/src/api-services/system-service.tsx +0 -34
  238. package/src/client.ts +0 -31
  239. package/src/components/documents/button.tsx +0 -142
  240. package/src/components/documents/icon-box.tsx +0 -93
  241. package/src/components/documents/page-title.tsx +0 -7
  242. package/src/components/documents/tab-button.tsx +0 -172
  243. package/src/components/documents/tag.tsx +0 -30
  244. package/src/components/index.js +0 -0
  245. package/src/components/inputs/checkbox-input.tsx +0 -66
  246. package/src/components/inputs/input-box.tsx +0 -48
  247. package/src/components/inputs/input-element.tsx +0 -65
  248. package/src/components/inputs/input-form.tsx +0 -164
  249. package/src/components/inputs/input.tsx +0 -181
  250. package/src/components/inputs/number-input.tsx +0 -108
  251. package/src/components/inputs/radiobox-input.tsx +0 -53
  252. package/src/components/inputs/textarea-input.tsx +0 -47
  253. package/src/components/inputs/textbox-input.tsx +0 -45
  254. package/src/components/layouts/global-dialogbox.tsx +0 -431
  255. package/src/components/layouts/global-layout.tsx +0 -59
  256. package/src/components/layouts/layout-helpers.tsx +0 -20
  257. package/src/components/layouts/panels/user-panel.tsx +0 -112
  258. package/src/components/layouts/utility-menu.tsx +0 -49
  259. package/src/components/panels/theme-panel.tsx +0 -46
  260. package/src/helpers/bitwise-helpers.tsx +0 -11
  261. package/src/helpers/browser-helpers.tsx +0 -156
  262. package/src/helpers/datasource-helpers.tsx +0 -99
  263. package/src/helpers/element-helpers.tsx +0 -57
  264. package/src/helpers/input-helpers.tsx +0 -74
  265. package/src/helpers/string-helpers.tsx +0 -28
  266. package/src/helpers/utility-helpers.tsx +0 -45
  267. package/src/helpers/validation-helpers.tsx +0 -302
  268. package/src/index.ts +0 -26
  269. package/src/interface.ts +0 -19
  270. package/src/interfaces/auth-token-interfaces.tsx +0 -6
  271. package/src/interfaces/browser-interfaces.tsx +0 -36
  272. package/src/interfaces/button-interfaces.tsx +0 -63
  273. package/src/interfaces/datasource-interfaces.tsx +0 -22
  274. package/src/interfaces/datatable-interfaces.tsx +0 -25
  275. package/src/interfaces/dialogbox-interfaces.tsx +0 -5
  276. package/src/interfaces/exception-interfaces.tsx +0 -99
  277. package/src/interfaces/http-interfaces.tsx +0 -129
  278. package/src/interfaces/icon-interfaces.tsx +0 -129
  279. package/src/interfaces/input-interfaces.tsx +0 -410
  280. package/src/interfaces/layout-interfaces.tsx +0 -191
  281. package/src/interfaces/menu-interfaces.tsx +0 -49
  282. package/src/interfaces/message-interfaces.tsx +0 -32
  283. package/src/interfaces/permission-interfaces.tsx +0 -9
  284. package/src/interfaces/storage-interfaces.tsx +0 -5
  285. package/src/interfaces/system-interfaces.tsx +0 -22
  286. package/src/interfaces/theme-interfaces.tsx +0 -123
  287. package/src/interfaces/type-interfaces.tsx +0 -28
  288. package/src/interfaces/user-interfaces.tsx +0 -47
  289. package/src/nexus-client.tsx +0 -21
  290. package/src/nexus.environments.tsx +0 -66
  291. package/src/proxy-api/proxy-backend.tsx +0 -60
  292. package/src/proxy-api/proxy-constants.tsx +0 -28
  293. package/src/proxy-api/proxy-helpers.tsx +0 -91
  294. package/src/proxy-api-client.tsx +0 -1
  295. package/src/proxy-api-server.tsx +0 -2
  296. package/src/services/http-client-services.tsx +0 -75
  297. package/src/services/http-services.tsx +0 -158
  298. package/src/services/loader-service.tsx +0 -185
  299. package/src/services/localstorage-service.tsx +0 -119
  300. package/src/services/message-services.tsx +0 -383
  301. package/src/services/theme-service.tsx +0 -161
  302. package/src/services/user-services.tsx +0 -10
  303. package/src/sso-config/auth-token-validation.ts +0 -16
  304. package/src/sso-config/callback-route.tsx +0 -35
  305. package/src/sso-config/cookie-encryption.ts +0 -51
  306. package/src/sso-config/cookie-helpers.tsx +0 -102
  307. package/src/sso-config/forgot-password-route.tsx +0 -36
  308. package/src/sso-config/oauth-callback-state.ts +0 -61
  309. package/src/sso-config/pkce-helpers.ts +0 -9
  310. package/src/sso-config/provider-complete-route.tsx +0 -18
  311. package/src/sso-config/redirect-context-actions.tsx +0 -45
  312. package/src/sso-config/redirect-context-helpers.tsx +0 -159
  313. package/src/sso-config/redirect-context-persist.tsx +0 -18
  314. package/src/sso-config/redirect-context-route.tsx +0 -45
  315. package/src/sso-config/refresh-route.tsx +0 -23
  316. package/src/sso-config/sign-in-route.tsx +0 -74
  317. package/src/sso-config/sign-out-route.tsx +0 -57
  318. package/src/sso-config/sign-up-route.tsx +0 -57
  319. package/src/sso-config/sso-backend-flow.ts +0 -38
  320. package/src/sso-config/sso-complete-route.tsx +0 -50
  321. package/src/sso-config/sso-config.ts +0 -59
  322. package/src/sso-config/sso-interfaces.tsx +0 -99
  323. package/src/sso-config/sso-response-helpers.tsx +0 -20
  324. package/src/sso-server.tsx +0 -21
  325. package/src/styles/nexus.animation.css +0 -269
  326. package/src/styles/nexus.core.css +0 -119
  327. package/src/styles/nexus.dialog.css +0 -144
  328. package/src/styles/nexus.icon.css +0 -51
  329. package/src/styles/nexus.input.css +0 -207
  330. package/src/styles/nexus.loader.css +0 -11
  331. package/src/styles/nexus.logic.css +0 -47
  332. package/src/styles/nexus.utility.css +0 -347
@@ -1,102 +0,0 @@
1
- import { cookies } from "next/headers";
2
- import { NextRequest, NextResponse } from "next/server";
3
- import { VerifyAccessToken } from "./auth-token-validation";
4
- import { DecryptCookieValue, EncryptCookieValue } from "./cookie-encryption";
5
- import { GetAuthCookieOptions } from "./redirect-context-helpers";
6
- import { CookieInfo, SSOAuthResponse } from "./sso-interfaces";
7
- import { SSO_CONFIG } from "./sso-config";
8
-
9
- export const AUTH_COOKIES = {
10
- ssoSession: "sso_session",
11
- accessToken: "access_token",
12
- refreshToken: "refresh_token",
13
- redirectContext: "sso_redirect_ctx",
14
- } as const;
15
-
16
- export function SetAuthCookies(response: NextResponse, tokens: SSOAuthResponse) {
17
- response.cookies.set(AUTH_COOKIES.accessToken, EncryptCookieValue(tokens.accessToken), GetAuthCookieOptions(tokens.expiresTokenIn));
18
- response.cookies.set(AUTH_COOKIES.refreshToken, EncryptCookieValue(tokens.refreshToken), GetAuthCookieOptions(tokens.expiresRefreshTokenIn));
19
- }
20
-
21
- export function SetSsoSessionCookie(response: NextResponse, ssoSession: string, maxAge: number | string) {
22
- response.cookies.set(AUTH_COOKIES.ssoSession, EncryptCookieValue(ssoSession), GetAuthCookieOptions(maxAge ?? 28800));
23
- }
24
-
25
- export function ClearAuthCookies(response: NextResponse) {
26
- response.cookies.set(AUTH_COOKIES.accessToken, "", GetAuthCookieOptions(0));
27
- response.cookies.set(AUTH_COOKIES.refreshToken, "", GetAuthCookieOptions(0));
28
- response.cookies.set(AUTH_COOKIES.ssoSession, "", GetAuthCookieOptions(0));
29
- }
30
-
31
- /**
32
- * Reads and decrypts a single auth cookie from an incoming NextRequest.
33
- * Returns null when the cookie is absent or the encrypted value is tampered / unreadable.
34
- */
35
- export function GetDecryptedRequestCookie(req: NextRequest, name: string): string | null {
36
- const raw = req.cookies.get(name)?.value;
37
- if (!raw) return null;
38
- return DecryptCookieValue(raw);
39
- }
40
-
41
- export async function GetCookieInfo(): Promise<CookieInfo | null> {
42
- const cookieStore = await cookies();
43
-
44
- const rawRefreshToken = cookieStore.get(AUTH_COOKIES.refreshToken)?.value;
45
- const refreshToken = rawRefreshToken ? (DecryptCookieValue(rawRefreshToken) ?? undefined) : undefined;
46
-
47
- const rawSsoSession = cookieStore.get(AUTH_COOKIES.ssoSession)?.value;
48
- const ssoSession = rawSsoSession ? (DecryptCookieValue(rawSsoSession) ?? undefined) : undefined;
49
-
50
- const rawAccessToken = cookieStore.get(AUTH_COOKIES.accessToken)?.value;
51
- const accessToken = rawAccessToken ? (DecryptCookieValue(rawAccessToken) ?? undefined) : undefined;
52
-
53
- if (!refreshToken && !ssoSession) return null;
54
-
55
- return {
56
- ssoSession,
57
- accessToken,
58
- refreshToken,
59
- };
60
- }
61
-
62
- /** Where to send the browser after credentials or provider sign-in succeeds. */
63
- export function ResolvePostLoginRedirectUrl(hasRedirectContext: boolean): string {
64
- return hasRedirectContext ? SSO_CONFIG.FRONTEND_ENDPOINTS.SSO_COMPLETE : SSO_CONFIG.FRONTEND_ENDPOINTS.SIGN_IN;
65
- }
66
-
67
- /**
68
- * When the user already has auth cookies, returns the next URL (or null to show sign-in).
69
- * - refresh token → home or SSO complete for an external client
70
- * - sso session only → token exchange (GET sign-in) or SSO complete
71
- */
72
- export async function ResolveAuthenticatedRedirect(redirectContextUri?: string | null): Promise<string | null> {
73
- const cookieInfo = await GetCookieInfo();
74
- if (!cookieInfo) return null;
75
-
76
- if (cookieInfo.refreshToken) {
77
- return redirectContextUri ? SSO_CONFIG.FRONTEND_ENDPOINTS.SSO_COMPLETE : "/home";
78
- }
79
-
80
- if (cookieInfo.ssoSession) {
81
- return redirectContextUri ? SSO_CONFIG.FRONTEND_ENDPOINTS.SSO_COMPLETE : SSO_CONFIG.FRONTEND_ENDPOINTS.SIGN_IN;
82
- }
83
-
84
- return null;
85
- }
86
-
87
- /** True when this client app has a valid access token (use on all non-auth client sites). */
88
- export async function HasAccessToken(backendValidation: boolean = false): Promise<boolean> {
89
- const cookieStore = await cookies();
90
- const rawRefreshToken = cookieStore.get(AUTH_COOKIES.refreshToken)?.value;
91
- const refreshToken = rawRefreshToken ? DecryptCookieValue(rawRefreshToken) : null;
92
- if (!refreshToken) return false;
93
-
94
- const rawAccessToken = cookieStore.get(AUTH_COOKIES.accessToken)?.value;
95
- const accessToken = rawAccessToken ? DecryptCookieValue(rawAccessToken) : null;
96
-
97
- if (!accessToken && !backendValidation) return true;
98
-
99
- if (!accessToken) return false;
100
-
101
- return VerifyAccessToken(accessToken);
102
- }
@@ -1,36 +0,0 @@
1
- import { NextRequest, NextResponse } from "next/server";
2
- import { HttpPost } from "../services/http-services";
3
- import { SSO_CONFIG } from "./sso-config";
4
-
5
- export async function ForgotPasswordPostRoute(req: NextRequest) {
6
- const body = (await req.json()) as { usernameOrEmail?: string };
7
- if (!body.usernameOrEmail?.trim()) {
8
- return NextResponse.json({ error: "Username or email is required." }, { status: 400 });
9
- }
10
-
11
- const response = await HttpPost(SSO_CONFIG.BACKEND_ENDPOINTS.FORGOT_PASSWORD, {
12
- usernameOrEmail: body.usernameOrEmail.trim(),
13
- });
14
-
15
- if (!response.isSuccess) {
16
- return NextResponse.json(response, { status: response.code ?? 400 });
17
- }
18
-
19
- return NextResponse.json(response);
20
- }
21
-
22
- export async function ResetPasswordPostRoute(req: NextRequest) {
23
- const body = (await req.json()) as {
24
- resetSessionToken?: string;
25
- verificationCode?: string;
26
- newPassword?: string;
27
- confirmPassword?: string;
28
- };
29
-
30
- const response = await HttpPost(SSO_CONFIG.BACKEND_ENDPOINTS.RESET_PASSWORD, body);
31
- if (!response.isSuccess) {
32
- return NextResponse.json(response, { status: response.code ?? 400 });
33
- }
34
-
35
- return NextResponse.json(response);
36
- }
@@ -1,61 +0,0 @@
1
- import { createHmac, timingSafeEqual } from "crypto";
2
- import { SanitizeReturnPath } from "./redirect-context-helpers";
3
-
4
- type EncodedCallbackState = {
5
- n: string;
6
- p: string;
7
- v: string;
8
- t: number;
9
- };
10
-
11
- // @ts-ignore
12
- const processEnv = process.env;
13
-
14
- function getCookieSecret(): string {
15
- const ssoSecret = processEnv.SSO_COOKIE_SECRET?.trim();
16
- const secret = ssoSecret && !ssoSecret.startsWith("$") ? ssoSecret : undefined;
17
- if (secret) return secret;
18
- if (processEnv.NODE_ENV === "development") return "NexusDevAuthSecretKey2026MustBe32CharsLong!";
19
- throw new Error("SSO_COOKIE_SECRET must be configured.");
20
- }
21
-
22
- function signPayload(data: string): string {
23
- return createHmac("sha256", getCookieSecret()).update(data).digest("base64url");
24
- }
25
-
26
- /** Signed OAuth callback state (nonce + return path + PKCE verifier). */
27
- export function EncodeOAuthCallbackState(nonce: string, returnPath: string, codeVerifier: string): string {
28
- const payload: EncodedCallbackState = {
29
- n: nonce,
30
- p: SanitizeReturnPath(returnPath),
31
- v: codeVerifier,
32
- t: Date.now(),
33
- };
34
- const data = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
35
- return `${data}.${signPayload(data)}`;
36
- }
37
-
38
- export function DecodeOAuthCallbackState(value?: string | null): { nonce: string; returnPath: string; codeVerifier: string } | null {
39
- if (!value) return null;
40
-
41
- try {
42
- const [data, signature] = value.split(".");
43
- if (!data || !signature) return null;
44
-
45
- const expected = signPayload(data);
46
- if (signature.length !== expected.length || !timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
47
- return null;
48
- }
49
-
50
- const payload = JSON.parse(Buffer.from(data, "base64url").toString("utf8")) as EncodedCallbackState;
51
- if (!payload?.n || !payload?.v) return null;
52
-
53
- return {
54
- nonce: payload.n,
55
- returnPath: SanitizeReturnPath(payload.p),
56
- codeVerifier: payload.v,
57
- };
58
- } catch {
59
- return null;
60
- }
61
- }
@@ -1,9 +0,0 @@
1
- import { createHash, randomBytes } from "crypto";
2
- import { PKCE_METHOD_S256, PkcePair } from "./sso-interfaces";
3
-
4
- /** Creates an OAuth PKCE pair (RFC 7636) using S256. */
5
- export function CreatePkcePair(): PkcePair {
6
- const verifier = randomBytes(32).toString("base64url");
7
- const challenge = createHash("sha256").update(verifier).digest("base64url");
8
- return { verifier, challenge, method: PKCE_METHOD_S256 };
9
- }
@@ -1,18 +0,0 @@
1
- import { NextRequest, NextResponse } from "next/server";
2
- import { AUTH_COOKIES, ResolvePostLoginRedirectUrl, SetSsoSessionCookie } from "./cookie-helpers";
3
- import { DecodeRedirectContext } from "./redirect-context-helpers";
4
- import { GetClientConfiguration } from "./sso-backend-flow";
5
-
6
- /** GET — complete provider OAuth by persisting the backend SSO session cookie. */
7
- export async function ProviderCompleteRoute(req: NextRequest) {
8
- const signInUrl = new URL("/auth/sign-in", req.url);
9
- const ssoSession = req.nextUrl.searchParams.get("ssoSession");
10
-
11
- if (!ssoSession) return NextResponse.redirect(signInUrl);
12
- const ssoConfiguration = await GetClientConfiguration();
13
-
14
- const redirectContext = DecodeRedirectContext(req.cookies.get(AUTH_COOKIES.redirectContext)?.value);
15
- const response = NextResponse.redirect(new URL(ResolvePostLoginRedirectUrl(!!redirectContext?.redirectUri), req.url));
16
- SetSsoSessionCookie(response, ssoSession, ssoConfiguration.ssoSessionLifetime);
17
- return response;
18
- }
@@ -1,45 +0,0 @@
1
- "use server";
2
-
3
- import { cookies } from "next/headers";
4
- import { AUTH_COOKIES } from "./cookie-helpers";
5
- import { CreatePkcePair } from "./pkce-helpers";
6
- import { ClearRedirectContextStore, CreateOAuthNonce, DecodeRedirectContext, EncodeRedirectContext, GetRedirectContextCookieOptions, IsAllowedRedirectUri, SanitizeReturnPath } from "./redirect-context-helpers";
7
- import { IRedirectContext } from "./sso-interfaces";
8
-
9
- function ReadRedirectContextFromStore(cookieStore: Awaited<ReturnType<typeof cookies>>): IRedirectContext | null {
10
- return DecodeRedirectContext(cookieStore.get(AUTH_COOKIES.redirectContext)?.value);
11
- }
12
-
13
- function WriteRedirectContextToStore(cookieStore: Awaited<ReturnType<typeof cookies>>, context: IRedirectContext) {
14
- cookieStore.set(AUTH_COOKIES.redirectContext, EncodeRedirectContext(context), GetRedirectContextCookieOptions());
15
- }
16
-
17
- /** Server Action — persists redirect_uri/state into a signed httpOnly cookie. */
18
- export async function PersistRedirectContext(redirectUri?: string | null, state?: string | null) {
19
- const cookieStore = await cookies();
20
- const trimmedUri = redirectUri?.trim();
21
-
22
- if (trimmedUri && IsAllowedRedirectUri(trimmedUri)) {
23
- const existing = ReadRedirectContextFromStore(cookieStore);
24
- if (existing?.redirectUri === trimmedUri) return;
25
-
26
- const pkce = CreatePkcePair();
27
- WriteRedirectContextToStore(cookieStore, {
28
- redirectUri: trimmedUri,
29
- state: CreateOAuthNonce(),
30
- returnPath: SanitizeReturnPath(state),
31
- codeChallenge: pkce.challenge,
32
- codeChallengeMethod: pkce.method,
33
- pkceVerifier: pkce.verifier,
34
- });
35
- return;
36
- }
37
-
38
- const existing = ReadRedirectContextFromStore(cookieStore);
39
- if (existing) WriteRedirectContextToStore(cookieStore, existing);
40
- }
41
-
42
- /** Server Action — clears the redirect context cookie after SSO completes. */
43
- export async function ClearRedirectContext() {
44
- await ClearRedirectContextStore();
45
- }
@@ -1,159 +0,0 @@
1
- import { createHmac, randomBytes, timingSafeEqual } from "crypto";
2
- import { cookies } from "next/headers";
3
- import { NextResponse } from "next/server";
4
- import { NEXUS_INFO, URLS } from "../nexus.environments";
5
- import { AUTH_COOKIES } from "./cookie-helpers";
6
- import { CreatePkcePair } from "./pkce-helpers";
7
- import { SSO_CONFIG } from "./sso-config";
8
- import { IRedirectContext, PKCE_METHOD_S256 } from "./sso-interfaces";
9
-
10
- // @ts-ignore
11
- const processEnv = process.env;
12
- const CALLBACK_SUFFIX = "/api/auth/callback";
13
-
14
- type EncodedRedirectContext = {
15
- r: string;
16
- s: string;
17
- p: string;
18
- c: string;
19
- m: string;
20
- v: string;
21
- t: number;
22
- };
23
-
24
- const signPayload = (data: string): string => createHmac("sha256", SSO_CONFIG.COOKIE_CONFIG.COOKIE_SECRET).update(data).digest("base64url");
25
-
26
- export function SanitizeReturnPath(value?: string | null): string {
27
- if (!value?.trim()) return "/";
28
- const path = value.trim();
29
- if (!path.startsWith("/") || path.startsWith("//")) return "/";
30
- return path;
31
- }
32
-
33
- export function CreateOAuthNonce(): string {
34
- return randomBytes(24).toString("base64url");
35
- }
36
-
37
- /** Validates client callback URLs to prevent open redirects. */
38
- export function IsAllowedRedirectUri(redirectUri: string): boolean {
39
- try {
40
- const url = new URL(redirectUri);
41
- if (!url.pathname.endsWith(CALLBACK_SUFFIX)) return false;
42
- if (url.username || url.password) return false;
43
- if (url.protocol !== "http:" && url.protocol !== "https:") return false;
44
- return URLS.ALLOWED_ORIGINS.includes(url.origin);
45
- } catch {
46
- return false;
47
- }
48
- }
49
-
50
- export function EncodeRedirectContext(context: IRedirectContext): string {
51
- const payload: EncodedRedirectContext = {
52
- r: context.redirectUri,
53
- s: context.state,
54
- p: context.returnPath,
55
- c: context.codeChallenge,
56
- m: context.codeChallengeMethod,
57
- v: context.pkceVerifier,
58
- t: Date.now(),
59
- };
60
- const data = Buffer.from(JSON.stringify(payload), "utf8").toString("base64url");
61
- return `${data}.${signPayload(data)}`;
62
- }
63
-
64
- export function DecodeRedirectContext(value?: string | null): IRedirectContext | null {
65
- if (!value) return null;
66
-
67
- try {
68
- const [data, signature] = value.split(".");
69
- if (!data || !signature) return null;
70
-
71
- const expected = signPayload(data);
72
- if (signature.length !== expected.length || !timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
73
- return null;
74
- }
75
-
76
- const payload = JSON.parse(Buffer.from(data, "base64url").toString("utf8")) as EncodedRedirectContext;
77
- if (!payload?.r || !IsAllowedRedirectUri(payload.r)) return null;
78
-
79
- const ageMs = Date.now() - (payload.t ?? 0);
80
- if (ageMs > Number(SSO_CONFIG.BACKEND_CONFIG.REDIRECT_CONTEXT_MAX_AGE) * 1000) return null;
81
-
82
- if (!payload.c || !payload.v) return null;
83
-
84
- return {
85
- redirectUri: payload.r,
86
- state: payload.s ?? "",
87
- returnPath: SanitizeReturnPath(payload.p),
88
- codeChallenge: payload.c,
89
- codeChallengeMethod: payload.m ?? PKCE_METHOD_S256,
90
- pkceVerifier: payload.v,
91
- };
92
- } catch {
93
- return null;
94
- }
95
- }
96
-
97
- function createRedirectContext(redirectUri: string, returnPath?: string | null): IRedirectContext {
98
- const pkce = CreatePkcePair();
99
- return {
100
- redirectUri,
101
- state: CreateOAuthNonce(),
102
- returnPath: SanitizeReturnPath(returnPath),
103
- codeChallenge: pkce.challenge,
104
- codeChallengeMethod: pkce.method,
105
- pkceVerifier: pkce.verifier,
106
- };
107
- }
108
-
109
- /** Read-only: resolve redirect context from cookie, or build an in-memory context from URL params (no cookie writes). */
110
- export async function ReadRedirectContext(redirectUri?: string | null, state?: string | null): Promise<IRedirectContext | null> {
111
- const cookieStore = await cookies();
112
- const fromCookie = DecodeRedirectContext(cookieStore.get(AUTH_COOKIES.redirectContext)?.value);
113
-
114
- const trimmedUri = redirectUri?.trim();
115
- if (trimmedUri && IsAllowedRedirectUri(trimmedUri)) {
116
- if (fromCookie?.redirectUri === trimmedUri) {
117
- return fromCookie;
118
- }
119
- return createRedirectContext(trimmedUri, state);
120
- }
121
-
122
- return fromCookie;
123
- }
124
-
125
- export function GetAuthCookieOptions(maxAge: number | string) {
126
- return {
127
- httpOnly: true,
128
- path: "/",
129
- sameSite: "lax" as const,
130
- maxAge: Number(maxAge),
131
- secure: NEXUS_INFO.IS_PRODUCTION,
132
- };
133
- }
134
-
135
- export function GetRedirectContextCookieOptions() {
136
- return GetAuthCookieOptions(SSO_CONFIG.BACKEND_CONFIG.REDIRECT_CONTEXT_MAX_AGE);
137
- }
138
-
139
- export function SetRedirectContextCookie(response: NextResponse, context: IRedirectContext) {
140
- if (!IsAllowedRedirectUri(context.redirectUri)) return;
141
- response.cookies.set(AUTH_COOKIES.redirectContext, EncodeRedirectContext(context), GetRedirectContextCookieOptions());
142
- }
143
-
144
- const redirectContextClearOptions = () => ({
145
- ...GetRedirectContextCookieOptions(),
146
- maxAge: 0,
147
- expires: new Date(0),
148
- });
149
-
150
- /** Route Handler / middleware — clears redirect context on the outgoing response. */
151
- export function ClearRedirectContextCookie(response: NextResponse) {
152
- response.cookies.set(AUTH_COOKIES.redirectContext, "", redirectContextClearOptions());
153
- }
154
-
155
- /** Server Components / Server Actions — clears redirect context in the current request store. */
156
- export async function ClearRedirectContextStore() {
157
- const cookieStore = await cookies();
158
- cookieStore.set(AUTH_COOKIES.redirectContext, "", redirectContextClearOptions());
159
- }
@@ -1,18 +0,0 @@
1
- "use client";
2
-
3
- import { useSearchParams } from "next/navigation";
4
- import { useEffect } from "react";
5
- import { PersistRedirectContext } from "./redirect-context-actions";
6
-
7
- /** Keeps redirect_uri/state in a secure httpOnly cookie across auth page navigations. */
8
- export function RedirectContextPersist() {
9
- const searchParams = useSearchParams();
10
- const redirectUri = searchParams.get("redirect_uri");
11
- const state = searchParams.get("state");
12
-
13
- useEffect(() => {
14
- void PersistRedirectContext(redirectUri, state);
15
- }, [redirectUri, state]);
16
-
17
- return null;
18
- }
@@ -1,45 +0,0 @@
1
- import { NextRequest, NextResponse } from "next/server";
2
- import { AUTH_COOKIES } from "./cookie-helpers";
3
- import { CreatePkcePair } from "./pkce-helpers";
4
- import {
5
- CreateOAuthNonce,
6
- DecodeRedirectContext,
7
- IsAllowedRedirectUri,
8
- SanitizeReturnPath,
9
- SetRedirectContextCookie,
10
- } from "./redirect-context-helpers";
11
-
12
- /** Route Handler — persists redirect_uri/state in a signed cookie, then forwards to the auth sign-in page. */
13
- export async function RedirectContextRoute(req: NextRequest) {
14
- const redirectUri = req.nextUrl.searchParams.get("redirect_uri");
15
- const state = req.nextUrl.searchParams.get("state");
16
-
17
- const signInUrl = new URL("/auth/sign-in", req.url);
18
- if (redirectUri) signInUrl.searchParams.set("redirect_uri", redirectUri);
19
- if (state) signInUrl.searchParams.set("state", state);
20
-
21
- const response = NextResponse.redirect(signInUrl);
22
- const trimmedUri = redirectUri?.trim();
23
-
24
- if (!trimmedUri || !IsAllowedRedirectUri(trimmedUri)) {
25
- return response;
26
- }
27
-
28
- const existing = DecodeRedirectContext(req.cookies.get(AUTH_COOKIES.redirectContext)?.value);
29
- if (existing?.redirectUri === trimmedUri) {
30
- SetRedirectContextCookie(response, existing);
31
- return response;
32
- }
33
-
34
- const pkce = CreatePkcePair();
35
- SetRedirectContextCookie(response, {
36
- redirectUri: trimmedUri,
37
- state: CreateOAuthNonce(),
38
- returnPath: SanitizeReturnPath(state),
39
- codeChallenge: pkce.challenge,
40
- codeChallengeMethod: pkce.method,
41
- pkceVerifier: pkce.verifier,
42
- });
43
-
44
- return response;
45
- }
@@ -1,23 +0,0 @@
1
- import { NextRequest, NextResponse } from "next/server";
2
- import { GetResponse } from "nexus-shared/interface";
3
- import { HttpPost } from "../services/http-services";
4
- import { AUTH_COOKIES, GetDecryptedRequestCookie, SetAuthCookies } from "./cookie-helpers";
5
- import { SSO_CONFIG } from "./sso-config";
6
- import { SSOAuthResponse } from "./sso-interfaces";
7
-
8
- export async function RefreshRoute(req: NextRequest) {
9
- const refreshToken = GetDecryptedRequestCookie(req, AUTH_COOKIES.refreshToken);
10
- if (!refreshToken) return NextResponse.json(GetResponse.ERROR("No refresh token", "NJS_X1003"), { status: 401 });
11
-
12
- try {
13
- const refreshRes = await HttpPost(SSO_CONFIG.BACKEND_ENDPOINTS.REFRESH, { refreshToken, clientSystemName: SSO_CONFIG.BACKEND_CONFIG.CLIENT_SYSTEM_NAME });
14
- if (!refreshRes.isSuccess) return NextResponse.json(GetResponse.ERROR("Refresh failed", "NJS_X1001"), { status: 401 });
15
-
16
- const newTokens = refreshRes.result as SSOAuthResponse;
17
- const response = NextResponse.json(GetResponse.SUCCESS(null, "Refresh successful"));
18
- SetAuthCookies(response, newTokens);
19
- return response;
20
- } catch {
21
- return NextResponse.json(GetResponse.ERROR("Auth service unavailable", "NJS_X1002"), { status: 500 });
22
- }
23
- }
@@ -1,74 +0,0 @@
1
- import { NextRequest, NextResponse } from "next/server";
2
- import { EErrorCodes, EExceptionCategories } from "../interfaces/exception-interfaces";
3
- import { GetResponse } from "../interfaces/http-interfaces";
4
- import { URLS } from "../nexus.environments";
5
- import { HttpPost } from "../services/http-services";
6
- import { AUTH_COOKIES, GetDecryptedRequestCookie, ResolvePostLoginRedirectUrl, SetAuthCookies, SetSsoSessionCookie } from "./cookie-helpers";
7
- import { DecodeRedirectContext } from "./redirect-context-helpers";
8
- import { CreatePkcePair } from "./pkce-helpers";
9
- import { ClearRedirectContextCookie } from "./redirect-context-helpers";
10
- import { ExchangeAuthorizationCode, GetClientConfiguration, RequestAuthorizationCode } from "./sso-backend-flow";
11
- import { BuildAuthenticationSignInUrl, SSO_CONFIG } from "./sso-config";
12
- import { ILoginRequest, ILoginResponse } from "./sso-interfaces";
13
-
14
- function failRedirect(req: NextRequest) {
15
- const returnPath = req.nextUrl.searchParams.get("state") ?? "/";
16
- return NextResponse.redirect(new URL(BuildAuthenticationSignInUrl(returnPath)));
17
- }
18
-
19
- /** GET — exchange local sso_session for access tokens (identity provider app). */
20
- export async function SignInGetRoute(req: NextRequest) {
21
- const ssoSession = GetDecryptedRequestCookie(req, AUTH_COOKIES.ssoSession);
22
-
23
- if (!ssoSession) return failRedirect(req);
24
-
25
- const pkce = CreatePkcePair();
26
-
27
- try {
28
- const code = await RequestAuthorizationCode({
29
- ssoSession,
30
- redirectUri: SSO_CONFIG.FRONTEND_ENDPOINTS.CALLBACK,
31
- pkce,
32
- });
33
- if (!code) return failRedirect(req);
34
-
35
- const tokenData = await ExchangeAuthorizationCode({
36
- code,
37
- redirectUri: SSO_CONFIG.FRONTEND_ENDPOINTS.CALLBACK,
38
- codeVerifier: pkce.verifier,
39
- });
40
- if (!tokenData) return failRedirect(req);
41
-
42
- const response = NextResponse.redirect(new URL(URLS.CURRENT!));
43
- SetAuthCookies(response, tokenData);
44
- ClearRedirectContextCookie(response);
45
- return response;
46
- } catch {
47
- return failRedirect(req);
48
- }
49
- }
50
-
51
- /** POST — username/password sign-in (identity provider app). */
52
- export async function SignInPostRoute(req: NextRequest) {
53
- const body = (await req.json()) as ILoginRequest;
54
- body.clientSystemName = SSO_CONFIG.BACKEND_CONFIG.CLIENT_SYSTEM_NAME;
55
-
56
- if (!body.username?.trim() || !body.password) return NextResponse.json(GetResponse.ERROR("Username and password are required.", "USERNAME_AND_PASSWORD_REQUIRED", EExceptionCategories.Validation, EErrorCodes.FormatInvalid, "Username|Password"), { status: 400 });
57
-
58
- const signInRes = await HttpPost(SSO_CONFIG.BACKEND_ENDPOINTS.SIGN_IN, body);
59
-
60
- const signInResult = signInRes?.result as ILoginResponse;
61
-
62
- if (signInResult?.ssoSession) {
63
- const redirectContext = DecodeRedirectContext(req.cookies.get(AUTH_COOKIES.redirectContext)?.value);
64
- signInResult.redirectUrl = ResolvePostLoginRedirectUrl(!!redirectContext?.redirectUri);
65
- }
66
-
67
- if (!signInRes.isSuccess || !signInResult?.ssoSession) return NextResponse.json(signInRes, { status: signInRes.code ?? 401 });
68
-
69
- const ssoConfiguration = await GetClientConfiguration();
70
- const response = NextResponse.json(signInRes);
71
-
72
- SetSsoSessionCookie(response, signInResult.ssoSession, ssoConfiguration.ssoSessionLifetime);
73
- return response;
74
- }
@@ -1,57 +0,0 @@
1
- import { NextRequest, NextResponse } from "next/server";
2
- import { NEXUS_INFO, URLS } from "../nexus.environments";
3
- import { HttpPost } from "../services/http-services";
4
- import { AUTH_COOKIES, ClearAuthCookies, GetDecryptedRequestCookie } from "./cookie-helpers";
5
- import { SanitizeReturnPath } from "./redirect-context-helpers";
6
- import { SSO_CONFIG } from "./sso-config";
7
-
8
- function hasAuthSession(req: NextRequest): boolean {
9
- return !!(req.cookies.get(AUTH_COOKIES.ssoSession)?.value || req.cookies.get(AUTH_COOKIES.accessToken)?.value || req.cookies.get(AUTH_COOKIES.refreshToken)?.value);
10
- }
11
-
12
- function resolveReturnUrl(req: NextRequest): URL {
13
- if (NEXUS_INFO.IS_ADMIN_MODULE && !hasAuthSession(req)) {
14
- return new URL(URLS.SIGN_IN);
15
- }
16
-
17
- const appBase = req.nextUrl.origin ?? URLS.CURRENT!;
18
- const returnPath = req.nextUrl.searchParams.get("returnUrl");
19
- if (returnPath) {
20
- return new URL(SanitizeReturnPath(returnPath), appBase);
21
- }
22
-
23
- if (NEXUS_INFO.IS_ADMIN_MODULE) {
24
- return new URL(URLS.SIGN_IN);
25
- }
26
-
27
- return new URL(appBase);
28
- }
29
-
30
- async function revokeServerSession(req: NextRequest) {
31
- const ssoSession = GetDecryptedRequestCookie(req, AUTH_COOKIES.ssoSession);
32
- if (!ssoSession) return;
33
-
34
- const response = await HttpPost(SSO_CONFIG.BACKEND_ENDPOINTS.SIGN_OUT, { ssoSession });
35
-
36
- return response.isSuccess;
37
- }
38
-
39
- /** GET — clear cookies and redirect back to the originating app page. */
40
- export async function SignOutGetRoute(req: NextRequest) {
41
- await revokeServerSession(req);
42
- const response = NextResponse.redirect(resolveReturnUrl(req));
43
- ClearAuthCookies(response);
44
- return response;
45
- }
46
-
47
- /** POST — clear cookies and return JSON (API clients). */
48
- export async function SignOutPostRoute(req: NextRequest) {
49
- if (NEXUS_INFO.IS_ADMIN_MODULE && !hasAuthSession(req)) {
50
- return NextResponse.json({ ok: false, redirect: URLS.SIGN_IN }, { status: 401 });
51
- }
52
-
53
- await revokeServerSession(req);
54
- const response = NextResponse.json({ ok: true });
55
- ClearAuthCookies(response);
56
- return response;
57
- }