refactor(web): wire @bytelyst/react-auth into auth-context, clean platform-sync auth plumbing
This commit is contained in:
parent
bde5cb792d
commit
8a5a40676a
172
web/package-lock.json
generated
172
web/package-lock.json
generated
@ -8,7 +8,9 @@
|
||||
"name": "web",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@bytelyst/api-client": "file:../../learning_ai_common_plat/packages/api-client",
|
||||
"@bytelyst/auth-client": "file:../../learning_ai_common_plat/packages/auth-client",
|
||||
"@bytelyst/react-auth": "file:../../learning_ai_common_plat/packages/react-auth",
|
||||
"@bytelyst/telemetry-client": "file:../../learning_ai_common_plat/packages/telemetry-client",
|
||||
"@serwist/next": "^9.5.6",
|
||||
"date-fns": "^4.1.0",
|
||||
@ -40,10 +42,32 @@
|
||||
"vitest": "^4.0.18"
|
||||
}
|
||||
},
|
||||
"../../learning_ai_common_plat/packages/api-client": {
|
||||
"name": "@bytelyst/api-client",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"../../learning_ai_common_plat/packages/auth-client": {
|
||||
"name": "@bytelyst/auth-client",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"../../learning_ai_common_plat/packages/react-auth": {
|
||||
"name": "@bytelyst/react-auth",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@bytelyst/api-client": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "^16.3.2",
|
||||
"@types/react": "^19.2.14",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"happy-dom": "^18.0.1",
|
||||
"react": "^19.2.4",
|
||||
"react-dom": "^19.2.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"../../learning_ai_common_plat/packages/telemetry-client": {
|
||||
"name": "@bytelyst/telemetry-client",
|
||||
"version": "0.1.0"
|
||||
@ -164,7 +188,6 @@
|
||||
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.29.0",
|
||||
"@babel/generator": "^7.29.0",
|
||||
@ -397,10 +420,18 @@
|
||||
"specificity": "bin/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/@bytelyst/api-client": {
|
||||
"resolved": "../../learning_ai_common_plat/packages/api-client",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@bytelyst/auth-client": {
|
||||
"resolved": "../../learning_ai_common_plat/packages/auth-client",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@bytelyst/react-auth": {
|
||||
"resolved": "../../learning_ai_common_plat/packages/react-auth",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/@bytelyst/telemetry-client": {
|
||||
"resolved": "../../learning_ai_common_plat/packages/telemetry-client",
|
||||
"link": true
|
||||
@ -493,7 +524,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
@ -534,7 +564,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=20.19.0"
|
||||
}
|
||||
@ -1980,9 +2009,8 @@
|
||||
"version": "1.58.2",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/@playwright/test/-/test-1.58.2.tgz",
|
||||
"integrity": "sha512-akea+6bHYBBfA9uQqSYmlJXn61cTa+jbO87xVLCWbTqbWadRVmhxlXATaOjOgcBaWU4ePo0wB41KMFv3o35IXA==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"playwright": "1.58.2"
|
||||
},
|
||||
@ -2809,36 +2837,6 @@
|
||||
"tailwindcss": "4.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/dom": {
|
||||
"version": "10.4.1",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/@testing-library/dom/-/dom-10.4.1.tgz",
|
||||
"integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@types/aria-query": "^5.0.1",
|
||||
"aria-query": "5.3.0",
|
||||
"dom-accessibility-api": "^0.5.9",
|
||||
"lz-string": "^1.5.0",
|
||||
"picocolors": "1.1.1",
|
||||
"pretty-format": "^27.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/dom/node_modules/aria-query": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/aria-query/-/aria-query-5.3.0.tgz",
|
||||
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"dequal": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/jest-dom": {
|
||||
"version": "6.9.1",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz",
|
||||
@ -2905,13 +2903,6 @@
|
||||
"tslib": "^2.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/aria-query": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/@types/aria-query/-/aria-query-5.0.4.tgz",
|
||||
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/chai": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/@types/chai/-/chai-5.2.3.tgz",
|
||||
@ -3020,7 +3011,6 @@
|
||||
"integrity": "sha512-Uarfe6J91b9HAUXxjvSOdiO2UPOKLm07Q1oh0JHxoZ1y8HoqxDAu3gVrsrOHeiio0kSsoVBt4wFrKOm0dKxVPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"undici-types": "~6.21.0"
|
||||
}
|
||||
@ -3029,9 +3019,8 @@
|
||||
"version": "19.2.14",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/@types/react/-/react-19.2.14.tgz",
|
||||
"integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"csstype": "^3.2.2"
|
||||
}
|
||||
@ -3042,7 +3031,6 @@
|
||||
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"peerDependencies": {
|
||||
"@types/react": "^19.2.0"
|
||||
}
|
||||
@ -3111,7 +3099,6 @@
|
||||
"integrity": "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.56.1",
|
||||
"@typescript-eslint/types": "8.56.1",
|
||||
@ -3748,7 +3735,6 @@
|
||||
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@ -4128,7 +4114,6 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.9.0",
|
||||
"caniuse-lite": "^1.0.30001759",
|
||||
@ -4371,7 +4356,7 @@
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/csstype/-/csstype-3.2.3.tgz",
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/d3-array": {
|
||||
@ -4654,16 +4639,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/dequal": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/dequal/-/dequal-2.0.3.tgz",
|
||||
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/detect-libc": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/detect-libc/-/detect-libc-2.1.2.tgz",
|
||||
@ -4687,13 +4662,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-accessibility-api": {
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
|
||||
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
@ -5018,7 +4986,6 @@
|
||||
"integrity": "sha512-VmQ+sifHUbI/IcSopBCF/HO3YiHQx/AVd3UVyYL6weuwW+HvON9VYn5l6Zl1WZzPWXPNZrSQpxwkkZ/VuvJZzg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.8.0",
|
||||
"@eslint-community/regexpp": "^4.12.1",
|
||||
@ -5204,7 +5171,6 @@
|
||||
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@rtsao/scc": "^1.1.0",
|
||||
"array-includes": "^3.1.9",
|
||||
@ -6633,7 +6599,6 @@
|
||||
"integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@acemir/cssom": "^0.9.31",
|
||||
"@asamuzakjp/dom-selector": "^6.8.1",
|
||||
@ -7104,16 +7069,6 @@
|
||||
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/lz-string": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/lz-string/-/lz-string-1.5.0.tgz",
|
||||
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"lz-string": "bin/bin.js"
|
||||
}
|
||||
},
|
||||
"node_modules/magic-string": {
|
||||
"version": "0.30.21",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/magic-string/-/magic-string-0.30.21.tgz",
|
||||
@ -7260,7 +7215,6 @@
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/next/-/next-16.1.6.tgz",
|
||||
"integrity": "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@next/env": "16.1.6",
|
||||
"@swc/helpers": "0.5.15",
|
||||
@ -7674,7 +7628,7 @@
|
||||
"version": "1.58.2",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/playwright/-/playwright-1.58.2.tgz",
|
||||
"integrity": "sha512-vA30H8Nvkq/cPBnNw4Q8TWz1EJyqgpuinBcHET0YVJVFldr8JDNiU9LaWAE1KqSkRYazuaBhTpB5ZzShOezQ6A==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.58.2"
|
||||
@ -7693,7 +7647,7 @@
|
||||
"version": "1.58.2",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/playwright-core/-/playwright-core-1.58.2.tgz",
|
||||
"integrity": "sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
@ -7778,41 +7732,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-format": {
|
||||
"version": "27.5.1",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/pretty-format/-/pretty-format-27.5.1.tgz",
|
||||
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1",
|
||||
"ansi-styles": "^5.0.0",
|
||||
"react-is": "^17.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-format/node_modules/ansi-styles": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-format/node_modules/react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/react-is/-/react-is-17.0.2.tgz",
|
||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/prop-types": {
|
||||
"version": "15.8.1",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/prop-types/-/prop-types-15.8.1.tgz",
|
||||
@ -7860,7 +7779,6 @@
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/react/-/react-19.2.3.tgz",
|
||||
"integrity": "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@ -7870,7 +7788,6 @@
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/react-dom/-/react-dom-19.2.3.tgz",
|
||||
"integrity": "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"scheduler": "^0.27.0"
|
||||
},
|
||||
@ -7882,15 +7799,14 @@
|
||||
"version": "16.13.1",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/react-is/-/react-is-16.13.1.tgz",
|
||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-redux": {
|
||||
"version": "9.2.0",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/react-redux/-/react-redux-9.2.0.tgz",
|
||||
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/use-sync-external-store": "^0.0.6",
|
||||
"use-sync-external-store": "^1.4.0"
|
||||
@ -7957,8 +7873,7 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/redux/-/redux-5.0.1.tgz",
|
||||
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/redux-thunk": {
|
||||
"version": "3.1.0",
|
||||
@ -8938,7 +8853,6 @@
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@ -9155,9 +9069,8 @@
|
||||
"version": "5.9.3",
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/typescript/-/typescript-5.9.3.tgz",
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@ -9351,7 +9264,6 @@
|
||||
"integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.27.0",
|
||||
"fdir": "^6.5.0",
|
||||
@ -9445,7 +9357,6 @@
|
||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
@ -9844,7 +9755,6 @@
|
||||
"resolved": "https://jfrog-pkg-proxy.it.att.com/artifactory/api/npm/att-npm-proxy-group/zod/-/zod-4.3.6.tgz",
|
||||
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/colinhacks"
|
||||
}
|
||||
|
||||
@ -14,7 +14,9 @@
|
||||
"test:e2e:ui": "playwright test --ui"
|
||||
},
|
||||
"dependencies": {
|
||||
"@bytelyst/api-client": "file:../../learning_ai_common_plat/packages/api-client",
|
||||
"@bytelyst/auth-client": "file:../../learning_ai_common_plat/packages/auth-client",
|
||||
"@bytelyst/react-auth": "file:../../learning_ai_common_plat/packages/react-auth",
|
||||
"@bytelyst/telemetry-client": "file:../../learning_ai_common_plat/packages/telemetry-client",
|
||||
"@serwist/next": "^9.5.6",
|
||||
"date-fns": "^4.1.0",
|
||||
|
||||
@ -1,211 +1,73 @@
|
||||
// ── Auth Context ──────────────────────────────────────────────
|
||||
// Provides authentication state and actions for ChronoMind web.
|
||||
// Calls platform-service /auth/* endpoints for login/register/me.
|
||||
// Delegates to @bytelyst/react-auth shared package.
|
||||
|
||||
'use client';
|
||||
|
||||
import { createContext, useContext, useCallback, useEffect, useState, type ReactNode } from 'react';
|
||||
import {
|
||||
loginUser,
|
||||
registerUser,
|
||||
getMe,
|
||||
setAuthToken,
|
||||
setRefreshToken,
|
||||
setSyncEnabled,
|
||||
isAuthenticated as checkAuth,
|
||||
refreshAccessToken,
|
||||
forgotPassword as apiForgotPassword,
|
||||
resetPassword as apiResetPassword,
|
||||
changePassword as apiChangePassword,
|
||||
deleteAccount as apiDeleteAccount,
|
||||
type AuthUser,
|
||||
} from './platform-sync';
|
||||
import { createAuthProvider } from '@bytelyst/react-auth';
|
||||
import { setSyncEnabled } from './platform-sync';
|
||||
import { PRODUCT_ID, getAuthClient } from './auth-api';
|
||||
|
||||
interface AuthState {
|
||||
user: AuthUser | null;
|
||||
isLoading: boolean;
|
||||
isAuthenticated: boolean;
|
||||
error: string | null;
|
||||
interface ChronoMindUser {
|
||||
id: string;
|
||||
email: string;
|
||||
name: string;
|
||||
displayName: string;
|
||||
role: string;
|
||||
plan: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
interface AuthActions {
|
||||
login: (email: string, password: string) => Promise<boolean>;
|
||||
register: (email: string, password: string, displayName: string) => Promise<boolean>;
|
||||
logout: () => void;
|
||||
clearError: () => void;
|
||||
forgotPassword: (email: string) => Promise<boolean>;
|
||||
resetPassword: (token: string, newPassword: string) => Promise<boolean>;
|
||||
changePassword: (currentPassword: string, newPassword: string) => Promise<boolean>;
|
||||
deleteAccount: (password: string) => Promise<boolean>;
|
||||
successMessage: string | null;
|
||||
function getBaseUrl(): string {
|
||||
if (typeof window !== 'undefined' && (window as unknown as Record<string, unknown>).__PLATFORM_URL__) {
|
||||
return (window as unknown as Record<string, unknown>).__PLATFORM_URL__ as string;
|
||||
}
|
||||
return process.env.NEXT_PUBLIC_PLATFORM_SERVICE_URL ?? 'https://api.chronomind.app';
|
||||
}
|
||||
|
||||
type AuthContextValue = AuthState & AuthActions;
|
||||
|
||||
const AuthContext = createContext<AuthContextValue | null>(null);
|
||||
|
||||
export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
const [user, setUser] = useState<AuthUser | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [successMessage, setSuccessMessage] = useState<string | null>(null);
|
||||
|
||||
// Hydrate user from stored token on mount
|
||||
useEffect(() => {
|
||||
if (!checkAuth()) {
|
||||
setIsLoading(false);
|
||||
return;
|
||||
}
|
||||
getMe()
|
||||
.then((u) => setUser(u))
|
||||
.catch(() => {
|
||||
setAuthToken(null);
|
||||
})
|
||||
.finally(() => setIsLoading(false));
|
||||
}, []);
|
||||
|
||||
// Auto-refresh token every 45 minutes
|
||||
useEffect(() => {
|
||||
if (!user) return;
|
||||
const REFRESH_INTERVAL = 45 * 60 * 1000;
|
||||
const timer = setInterval(async () => {
|
||||
const refreshed = await refreshAccessToken();
|
||||
if (!refreshed) {
|
||||
setUser(null);
|
||||
}
|
||||
}, REFRESH_INTERVAL);
|
||||
return () => clearInterval(timer);
|
||||
}, [user]);
|
||||
|
||||
const login = useCallback(async (email: string, password: string): Promise<boolean> => {
|
||||
setError(null);
|
||||
try {
|
||||
const result = await loginUser(email, password);
|
||||
setAuthToken(result.accessToken);
|
||||
setRefreshToken(result.refreshToken);
|
||||
const { AuthProvider: _AuthProvider, useAuth: _useAuth } = createAuthProvider<ChronoMindUser>({
|
||||
baseUrl: getBaseUrl(),
|
||||
storagePrefix: 'chronomind',
|
||||
loginEndpoint: '/auth/login',
|
||||
registerEndpoint: '/auth/register',
|
||||
forgotPasswordEndpoint: '/auth/forgot-password',
|
||||
changePasswordEndpoint: '/auth/change-password',
|
||||
deleteAccountEndpoint: '/auth/account',
|
||||
refreshEndpoint: '/auth/refresh',
|
||||
mapLoginResponse: (data: unknown) => {
|
||||
const d = data as { user: { id: string; email: string; displayName: string; role: string; plan: string }; accessToken: string; refreshToken: string };
|
||||
setSyncEnabled(true);
|
||||
setUser(result.user);
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Login failed');
|
||||
return false;
|
||||
}
|
||||
}, []);
|
||||
return {
|
||||
user: { id: d.user.id, email: d.user.email, name: d.user.displayName, displayName: d.user.displayName, role: d.user.role, plan: d.user.plan },
|
||||
accessToken: d.accessToken,
|
||||
refreshToken: d.refreshToken,
|
||||
};
|
||||
},
|
||||
onLogout: () => setSyncEnabled(false),
|
||||
});
|
||||
|
||||
const register = useCallback(
|
||||
async (email: string, password: string, displayName: string): Promise<boolean> => {
|
||||
setError(null);
|
||||
export const AuthProvider = _AuthProvider;
|
||||
|
||||
/**
|
||||
* Wrapper around shared useAuth that adapts naming for backward compat:
|
||||
* - success → successMessage
|
||||
* - clearMessages → clearError
|
||||
*/
|
||||
export function useAuth() {
|
||||
const ctx = _useAuth();
|
||||
return {
|
||||
...ctx,
|
||||
successMessage: ctx.success,
|
||||
clearError: ctx.clearMessages,
|
||||
resetPassword: async (token: string, newPassword: string): Promise<boolean> => {
|
||||
try {
|
||||
const result = await registerUser(email, password, displayName);
|
||||
setAuthToken(result.accessToken);
|
||||
setRefreshToken(result.refreshToken);
|
||||
setSyncEnabled(true);
|
||||
setUser(result.user);
|
||||
await getAuthClient().resetPassword(token, newPassword);
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Registration failed');
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const logout = useCallback(() => {
|
||||
setAuthToken(null);
|
||||
setSyncEnabled(false);
|
||||
setUser(null);
|
||||
}, []);
|
||||
|
||||
const clearError = useCallback(() => {
|
||||
setError(null);
|
||||
setSuccessMessage(null);
|
||||
}, []);
|
||||
|
||||
const forgotPassword = useCallback(async (email: string): Promise<boolean> => {
|
||||
setError(null);
|
||||
setSuccessMessage(null);
|
||||
try {
|
||||
const result = await apiForgotPassword(email);
|
||||
setSuccessMessage(result.message);
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to send reset email');
|
||||
return false;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const resetPassword = useCallback(async (token: string, newPassword: string): Promise<boolean> => {
|
||||
setError(null);
|
||||
setSuccessMessage(null);
|
||||
try {
|
||||
const result = await apiResetPassword(token, newPassword);
|
||||
setSuccessMessage(result.message);
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to reset password');
|
||||
return false;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const changePassword = useCallback(
|
||||
async (currentPassword: string, newPassword: string): Promise<boolean> => {
|
||||
setError(null);
|
||||
setSuccessMessage(null);
|
||||
try {
|
||||
const result = await apiChangePassword(currentPassword, newPassword);
|
||||
setSuccessMessage(result.message);
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to change password');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const deleteAccount = useCallback(
|
||||
async (password: string): Promise<boolean> => {
|
||||
setError(null);
|
||||
try {
|
||||
await apiDeleteAccount(password);
|
||||
setAuthToken(null);
|
||||
setSyncEnabled(false);
|
||||
setUser(null);
|
||||
setSuccessMessage('Account deleted successfully.');
|
||||
return true;
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Failed to delete account');
|
||||
return false;
|
||||
}
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
return (
|
||||
<AuthContext.Provider
|
||||
value={{
|
||||
user,
|
||||
isLoading,
|
||||
isAuthenticated: user !== null,
|
||||
error,
|
||||
successMessage,
|
||||
login,
|
||||
register,
|
||||
logout,
|
||||
clearError,
|
||||
forgotPassword,
|
||||
resetPassword,
|
||||
changePassword,
|
||||
deleteAccount,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</AuthContext.Provider>
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export function useAuth(): AuthContextValue {
|
||||
const ctx = useContext(AuthContext);
|
||||
if (!ctx) throw new Error('useAuth must be used within AuthProvider');
|
||||
return ctx;
|
||||
}
|
||||
export type { ChronoMindUser as AuthUser };
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
|
||||
import type { Timer } from './timer-engine';
|
||||
import { getAuthClient, PRODUCT_ID as _PRODUCT_ID } from './auth-api';
|
||||
import type { AuthUser, AuthResult } from '@bytelyst/auth-client';
|
||||
|
||||
// ── DTOs ──────────────────────────────────────────────────────
|
||||
|
||||
@ -223,45 +222,13 @@ function setLastSyncDate(date: string): void {
|
||||
}
|
||||
|
||||
// ── Auth Operations (delegated to @bytelyst/auth-client) ─────
|
||||
|
||||
export type { AuthUser, AuthResult };
|
||||
|
||||
export async function loginUser(email: string, password: string): Promise<AuthResult> {
|
||||
return getAuthClient().login(email, password);
|
||||
}
|
||||
|
||||
export async function registerUser(email: string, password: string, displayName: string): Promise<AuthResult> {
|
||||
return getAuthClient().register(email, password, displayName);
|
||||
}
|
||||
|
||||
export async function getMe(): Promise<AuthUser> {
|
||||
return getAuthClient().getMe();
|
||||
}
|
||||
|
||||
export async function forgotPassword(email: string): Promise<{ message: string }> {
|
||||
return getAuthClient().forgotPassword(email);
|
||||
}
|
||||
|
||||
export async function resetPassword(token: string, newPassword: string): Promise<{ message: string }> {
|
||||
return getAuthClient().resetPassword(token, newPassword);
|
||||
}
|
||||
|
||||
export async function changePassword(currentPassword: string, newPassword: string): Promise<{ message: string }> {
|
||||
return getAuthClient().changePassword(currentPassword, newPassword);
|
||||
}
|
||||
// Most auth operations are now handled by @bytelyst/react-auth in auth-context.tsx.
|
||||
// Only verifyEmail is still used directly by the verify-email page.
|
||||
|
||||
export async function verifyEmail(token: string): Promise<{ message: string }> {
|
||||
return getAuthClient().verifyEmail(token);
|
||||
}
|
||||
|
||||
export async function resendVerification(email: string): Promise<{ message: string }> {
|
||||
return getAuthClient().resendVerification(email);
|
||||
}
|
||||
|
||||
export async function deleteAccount(password: string): Promise<{ message: string }> {
|
||||
return getAuthClient().deleteAccount(password);
|
||||
}
|
||||
|
||||
// ── Sync Operations ───────────────────────────────────────────
|
||||
|
||||
export async function pullDelta(since?: string): Promise<SyncTimerDTO[]> {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user