@sbc-connect/nuxt-auth 0.9.4 → 0.11.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.
- package/CHANGELOG.md +24 -0
- package/app/composables/useConnectLaunchDarkly.ts +116 -111
- package/nuxt.config.ts +8 -0
- package/package.json +11 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @sbc-connect/nuxt-auth
|
|
2
2
|
|
|
3
|
+
## 0.11.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#160](https://github.com/bcgov/connect-nuxt/pull/160) [`80b8318`](https://github.com/bcgov/connect-nuxt/commit/80b8318ab802a14f77e9fe88f96e66aaf23e18ad) Thanks [@deetz99](https://github.com/deetz99)! - Update Nuxt, pinia colada, keycloak, nuxt ui, i18n, vueuse, dompurify, es-toolkit, zod.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`80b8318`](https://github.com/bcgov/connect-nuxt/commit/80b8318ab802a14f77e9fe88f96e66aaf23e18ad)]:
|
|
12
|
+
- @sbc-connect/nuxt-base@0.9.0
|
|
13
|
+
- @sbc-connect/nuxt-forms@0.7.4
|
|
14
|
+
|
|
15
|
+
## 0.10.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- [#158](https://github.com/bcgov/connect-nuxt/pull/158) [`fe5065e`](https://github.com/bcgov/connect-nuxt/commit/fe5065e12d776349e7093e52ecee51ce22a2c271) Thanks [@vysakh-menon-aot](https://github.com/vysakh-menon-aot)! - Switch LD dependency to js-client-sdk
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Updated dependencies [[`a68fff2`](https://github.com/bcgov/connect-nuxt/commit/a68fff28bf29913c7643b570982568894b7d0704), [`fe5065e`](https://github.com/bcgov/connect-nuxt/commit/fe5065e12d776349e7093e52ecee51ce22a2c271)]:
|
|
24
|
+
- @sbc-connect/nuxt-forms@0.7.3
|
|
25
|
+
- @sbc-connect/nuxt-base@0.8.0
|
|
26
|
+
|
|
3
27
|
## 0.9.4
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
|
@@ -1,129 +1,133 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { LDClient, LDFlagSet, LDOptions, LDMultiKindContext } from 'launchdarkly
|
|
1
|
+
import { createClient } from '@launchdarkly/js-client-sdk'
|
|
2
|
+
import type { LDClient, LDFlagSet, LDOptions, LDMultiKindContext } from '@launchdarkly/js-client-sdk'
|
|
3
3
|
import { isEqual } from 'es-toolkit'
|
|
4
4
|
|
|
5
|
-
//
|
|
5
|
+
// Default anonymous context
|
|
6
6
|
const anonymousContext: LDMultiKindContext = {
|
|
7
7
|
kind: 'multi',
|
|
8
8
|
org: { key: 'anonymous' },
|
|
9
9
|
user: { key: 'anonymous' }
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
key: authUser.value.keycloakGuid,
|
|
32
|
-
firstName: authUser.value.firstName,
|
|
33
|
-
lastName: authUser.value.lastName,
|
|
34
|
-
email: authUser.value.email,
|
|
35
|
-
roles: authUser.value.roles,
|
|
36
|
-
loginSource: authUser.value.loginSource,
|
|
37
|
-
appSource: appName
|
|
38
|
-
}
|
|
12
|
+
/**
|
|
13
|
+
* Composable for the LaunchDarkly service.
|
|
14
|
+
* Extends the base composable with authenticated user and account context.
|
|
15
|
+
*/
|
|
16
|
+
export const useConnectLaunchDarkly = () => {
|
|
17
|
+
const ldClient = useState<LDClient | null>('ld-client', () => null)
|
|
18
|
+
const ldFlagSet = useState<LDFlagSet>('ld-flag-set', () => ({}))
|
|
19
|
+
const ldContext = useState<LDMultiKindContext>('ld-context', () => anonymousContext)
|
|
20
|
+
const ldInitialized = useState<boolean>('ld-initialized', () => false)
|
|
21
|
+
const isInitializing = useState<boolean>('ld-is-initializing', () => false)
|
|
22
|
+
|
|
23
|
+
function _createLdContext(): LDMultiKindContext {
|
|
24
|
+
const appName = useRuntimeConfig().public.appName
|
|
25
|
+
const { authUser, isAuthenticated } = useConnectAuth()
|
|
26
|
+
const account = useConnectAccountStore().currentAccount
|
|
27
|
+
|
|
28
|
+
if (!isAuthenticated.value) {
|
|
29
|
+
return anonymousContext
|
|
30
|
+
}
|
|
39
31
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
accountStatus: account.accountStatus,
|
|
49
|
-
type: account.type,
|
|
50
|
-
label: account.label,
|
|
32
|
+
// Create user context
|
|
33
|
+
const user = {
|
|
34
|
+
key: authUser.value.keycloakGuid,
|
|
35
|
+
firstName: authUser.value.firstName,
|
|
36
|
+
lastName: authUser.value.lastName,
|
|
37
|
+
email: authUser.value.email,
|
|
38
|
+
roles: authUser.value.roles,
|
|
39
|
+
loginSource: authUser.value.loginSource,
|
|
51
40
|
appSource: appName
|
|
52
41
|
}
|
|
53
|
-
}
|
|
54
42
|
|
|
55
|
-
|
|
56
|
-
}
|
|
43
|
+
// Default org to user key if no account
|
|
44
|
+
let org: Partial<ConnectAccount> & { key: string, appSource: string } = { key: user.key, appSource: appName }
|
|
45
|
+
|
|
46
|
+
// Use account info if available
|
|
47
|
+
if (account.id) {
|
|
48
|
+
org = {
|
|
49
|
+
key: String(account.id),
|
|
50
|
+
accountType: account.accountType,
|
|
51
|
+
accountStatus: account.accountStatus,
|
|
52
|
+
type: account.type,
|
|
53
|
+
label: account.label,
|
|
54
|
+
appSource: appName
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
if (!ldClient.value) {
|
|
60
|
-
return
|
|
58
|
+
return { kind: 'multi', org, user }
|
|
61
59
|
}
|
|
62
60
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
61
|
+
function _updateLdContext() {
|
|
62
|
+
if (!ldClient.value) {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
67
65
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
console.error('LaunchDarkly: Failed to update context.', error)
|
|
73
|
-
})
|
|
74
|
-
}
|
|
66
|
+
const newContext = _createLdContext()
|
|
67
|
+
if (isEqual(ldContext.value, newContext)) {
|
|
68
|
+
return
|
|
69
|
+
}
|
|
75
70
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// Prevent re-initialization
|
|
83
|
-
if (ldInitialized.value || isInitializing.value) {
|
|
84
|
-
return
|
|
85
|
-
}
|
|
86
|
-
// Prevent initialization if missing client ID
|
|
87
|
-
if (!rtc.ldClientId) {
|
|
88
|
-
console.error('LaunchDarkly: ldClientId is not configured.')
|
|
89
|
-
return
|
|
71
|
+
ldContext.value = newContext
|
|
72
|
+
ldClient.value.identify(newContext).then(() => {
|
|
73
|
+
ldFlagSet.value = ldClient.value?.allFlags() || {}
|
|
74
|
+
}).catch((error) => {
|
|
75
|
+
console.error('LaunchDarkly: Failed to update context.', error)
|
|
76
|
+
})
|
|
90
77
|
}
|
|
91
78
|
|
|
92
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Initializes the LaunchDarkly client.
|
|
81
|
+
*/
|
|
82
|
+
function _init(): void {
|
|
83
|
+
const rtc = useRuntimeConfig().public
|
|
93
84
|
|
|
94
|
-
|
|
85
|
+
// Prevent re-initialization
|
|
86
|
+
if (ldInitialized.value || isInitializing.value) {
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
// Prevent initialization if missing client ID
|
|
90
|
+
if (!rtc.ldClientId) {
|
|
91
|
+
console.error('LaunchDarkly: ldClientId is not configured.')
|
|
92
|
+
return
|
|
93
|
+
}
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
streaming: false,
|
|
98
|
-
useReport: false,
|
|
99
|
-
diagnosticOptOut: true
|
|
100
|
-
}
|
|
95
|
+
isInitializing.value = true
|
|
101
96
|
|
|
102
|
-
|
|
103
|
-
ldClient.value = initialize(rtc.ldClientId, ldContext.value, options)
|
|
97
|
+
ldContext.value = _createLdContext()
|
|
104
98
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
})
|
|
99
|
+
const options: LDOptions = {
|
|
100
|
+
streaming: false,
|
|
101
|
+
useReport: false,
|
|
102
|
+
diagnosticOptOut: true
|
|
103
|
+
}
|
|
111
104
|
|
|
112
|
-
|
|
113
|
-
|
|
105
|
+
try {
|
|
106
|
+
const client = createClient(rtc.ldClientId, ldContext.value, options)
|
|
107
|
+
|
|
108
|
+
client.start().then((result) => {
|
|
109
|
+
if (result.status === 'complete') {
|
|
110
|
+
ldInitialized.value = true
|
|
111
|
+
isInitializing.value = false
|
|
112
|
+
ldFlagSet.value = client.allFlags()
|
|
113
|
+
console.info('LaunchDarkly: Initialization complete.')
|
|
114
|
+
} else {
|
|
115
|
+
console.error('LaunchDarkly: Initialization did not complete.', result)
|
|
116
|
+
isInitializing.value = false
|
|
117
|
+
}
|
|
118
|
+
}).catch((error) => {
|
|
119
|
+
console.error('LaunchDarkly: Initialization error.', error)
|
|
120
|
+
isInitializing.value = false
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
ldClient.value = client
|
|
124
|
+
} catch (error) {
|
|
125
|
+
console.error('LaunchDarkly: Failed to initialize.', error)
|
|
114
126
|
isInitializing.value = false
|
|
115
|
-
}
|
|
116
|
-
} catch (error) {
|
|
117
|
-
console.error('LaunchDarkly: Failed to initialize.', error)
|
|
118
|
-
isInitializing.value = false
|
|
127
|
+
}
|
|
119
128
|
}
|
|
120
|
-
}
|
|
121
129
|
|
|
122
|
-
|
|
123
|
-
* Composable for the LaunchDarkly service.
|
|
124
|
-
*/
|
|
125
|
-
export const useConnectLaunchDarkly = () => {
|
|
126
|
-
// initialize only once
|
|
130
|
+
// Initialize only once on the client
|
|
127
131
|
if (!ldInitialized.value && !isInitializing.value && import.meta.client) {
|
|
128
132
|
_init()
|
|
129
133
|
}
|
|
@@ -171,12 +175,12 @@ export const useConnectLaunchDarkly = () => {
|
|
|
171
175
|
if (!ldClient.value) {
|
|
172
176
|
return Promise.resolve(defaultValue)
|
|
173
177
|
}
|
|
174
|
-
return ldClient.value.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
178
|
+
return ldClient.value.waitForInitialization().then(() =>
|
|
179
|
+
ldClient.value ? ldClient.value.variation(name, defaultValue) : defaultValue
|
|
180
|
+
).catch((error) => {
|
|
181
|
+
console.error(`LaunchDarkly: Error waiting for client while getting flag "${name}".`, error)
|
|
182
|
+
return defaultValue
|
|
183
|
+
})
|
|
180
184
|
}
|
|
181
185
|
|
|
182
186
|
return readonly(computed(() => {
|
|
@@ -206,12 +210,12 @@ export const useConnectLaunchDarkly = () => {
|
|
|
206
210
|
if (!ldClient.value) {
|
|
207
211
|
return Promise.resolve(defaultValue)
|
|
208
212
|
}
|
|
209
|
-
return ldClient.value.
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
return ldClient.value.waitForInitialization().then(() =>
|
|
214
|
+
ldFlagSet.value[name] ?? defaultValue
|
|
215
|
+
).catch((error) => {
|
|
216
|
+
console.error(`LaunchDarkly: Error waiting for client while getting stored flag "${name}".`, error)
|
|
217
|
+
return defaultValue
|
|
218
|
+
})
|
|
215
219
|
}
|
|
216
220
|
|
|
217
221
|
// reactive mode
|
|
@@ -232,6 +236,7 @@ export const useConnectLaunchDarkly = () => {
|
|
|
232
236
|
ldClient.value?.close()
|
|
233
237
|
ldClient.value = null
|
|
234
238
|
ldFlagSet.value = {}
|
|
239
|
+
ldContext.value = anonymousContext
|
|
235
240
|
}
|
|
236
241
|
|
|
237
242
|
return {
|
package/nuxt.config.ts
CHANGED
|
@@ -80,5 +80,13 @@ export default defineNuxtConfig({
|
|
|
80
80
|
playwright: process.env.playwright === 'true',
|
|
81
81
|
playwrightFetchTestAccount: process.env.playwrightFetchTestAccount === 'true'
|
|
82
82
|
}
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
vite: {
|
|
86
|
+
optimizeDeps: {
|
|
87
|
+
include: [
|
|
88
|
+
'keycloak-js'
|
|
89
|
+
]
|
|
90
|
+
}
|
|
83
91
|
}
|
|
84
92
|
})
|
package/package.json
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sbc-connect/nuxt-auth",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.11.0",
|
|
5
5
|
"repository": "github:bcgov/connect-nuxt",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
7
7
|
"main": "./nuxt.config.ts",
|
|
8
8
|
"devDependencies": {
|
|
9
|
-
"@axe-core/playwright": "4.11.
|
|
10
|
-
"dotenv": "17.
|
|
11
|
-
"nuxt": "4.
|
|
9
|
+
"@axe-core/playwright": "4.11.3",
|
|
10
|
+
"dotenv": "17.4.2",
|
|
11
|
+
"nuxt": "4.4.6",
|
|
12
12
|
"typescript": "5.9.3",
|
|
13
13
|
"vue-tsc": "3.2.5",
|
|
14
14
|
"@sbc-connect/eslint-config": "0.0.8",
|
|
15
|
-
"@sbc-connect/
|
|
16
|
-
"@sbc-connect/
|
|
15
|
+
"@sbc-connect/vitest-config": "0.2.0",
|
|
16
|
+
"@sbc-connect/playwright-config": "0.2.0"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@pinia/colada": "1.
|
|
20
|
-
"@pinia/colada-nuxt": "0.
|
|
19
|
+
"@pinia/colada": "1.3.0",
|
|
20
|
+
"@pinia/colada-nuxt": "1.0.1",
|
|
21
21
|
"@pinia/nuxt": "0.11.3",
|
|
22
|
-
"keycloak-js": "26.2.
|
|
22
|
+
"keycloak-js": "26.2.4",
|
|
23
23
|
"pinia": "3.0.4",
|
|
24
24
|
"pinia-plugin-persistedstate": "4.7.1",
|
|
25
|
-
"@sbc-connect/nuxt-base": "0.
|
|
26
|
-
"@sbc-connect/nuxt-forms": "0.7.
|
|
25
|
+
"@sbc-connect/nuxt-base": "0.9.0",
|
|
26
|
+
"@sbc-connect/nuxt-forms": "0.7.4"
|
|
27
27
|
},
|
|
28
28
|
"scripts": {
|
|
29
29
|
"preinstall": "npx only-allow pnpm",
|