@owlmeans/web-oidc-rp 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +39 -477
- package/build/@/components/ui/progress.d.ts +5 -0
- package/build/@/components/ui/progress.d.ts.map +1 -0
- package/build/@/components/ui/progress.js +11 -0
- package/build/@/components/ui/progress.js.map +1 -0
- package/build/@/lib/utils.d.ts +3 -0
- package/build/@/lib/utils.d.ts.map +1 -0
- package/build/@/lib/utils.js +6 -0
- package/build/@/lib/utils.js.map +1 -0
- package/build/auth/plugins/google-client.d.ts +3 -0
- package/build/auth/plugins/google-client.d.ts.map +1 -0
- package/build/auth/plugins/google-client.js +71 -0
- package/build/auth/plugins/google-client.js.map +1 -0
- package/build/auth/plugins/helpers.d.ts +16 -0
- package/build/auth/plugins/helpers.d.ts.map +1 -0
- package/build/auth/plugins/helpers.js +31 -0
- package/build/auth/plugins/helpers.js.map +1 -0
- package/build/auth/plugins/index.d.ts.map +1 -1
- package/build/auth/plugins/index.js +3 -1
- package/build/auth/plugins/index.js.map +1 -1
- package/build/auth/plugins/oidc-client.d.ts.map +1 -1
- package/build/auth/plugins/oidc-client.js +6 -2
- package/build/auth/plugins/oidc-client.js.map +1 -1
- package/build/guard.d.ts +3 -2
- package/build/guard.d.ts.map +1 -1
- package/build/guard.js +5 -4
- package/build/guard.js.map +1 -1
- package/build/service.d.ts.map +1 -1
- package/build/service.js +12 -3
- package/build/service.js.map +1 -1
- package/build/types.d.ts +6 -0
- package/build/types.d.ts.map +1 -1
- package/components.json +21 -0
- package/package.json +40 -19
- package/src/@/components/ui/progress.tsx +44 -0
- package/src/@/globals.css +17 -0
- package/src/@/lib/utils.ts +6 -0
- package/src/auth/plugins/google-client.tsx +94 -0
- package/src/auth/plugins/helpers.ts +39 -0
- package/src/auth/plugins/index.ts +3 -1
- package/src/auth/plugins/oidc-client.tsx +6 -2
- package/src/guard.ts +13 -10
- package/src/service.ts +13 -3
- package/src/types.ts +7 -0
- package/tests/context.ts +16 -0
- package/tests/google-client.spec.ts +64 -0
- package/tests/tsconfig.json +12 -0
- package/tsconfig.json +9 -11
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
|
|
2
|
+
import type { AuthenticationPlugin } from '@owlmeans/client-auth/manager/plugins'
|
|
3
|
+
import { AuthenticationStage, CAUTHEN_AUTHEN_TYPED } from '@owlmeans/auth'
|
|
4
|
+
import type { AuthCredentials } from '@owlmeans/auth'
|
|
5
|
+
import { DEFAULT_ALIAS as AUTH_SERVICE } from '@owlmeans/client-auth'
|
|
6
|
+
import type { AuthService } from '@owlmeans/auth-common'
|
|
7
|
+
import { GOOGLE_CLIENT_AUTH } from '@owlmeans/oidc'
|
|
8
|
+
import { useContext, useValue } from '@owlmeans/client'
|
|
9
|
+
import { HOME } from '@owlmeans/web-client'
|
|
10
|
+
import type { Module } from '@owlmeans/web-client'
|
|
11
|
+
import { Progress } from '@/components/ui/progress'
|
|
12
|
+
import { extractGoogleUrl, buildCallbackCredentials } from './helpers.js'
|
|
13
|
+
|
|
14
|
+
export const googleClientPlugin: AuthenticationPlugin = {
|
|
15
|
+
type: GOOGLE_CLIENT_AUTH,
|
|
16
|
+
|
|
17
|
+
Implementation: Renderer => ({ type, stage, control }) => {
|
|
18
|
+
const context = useContext()
|
|
19
|
+
Renderer = Renderer ?? googleClientPlugin.Renderer
|
|
20
|
+
|
|
21
|
+
useValue(async cancel => {
|
|
22
|
+
switch (control.stage) {
|
|
23
|
+
case AuthenticationStage.Init: {
|
|
24
|
+
const hasState = await control.hasPersistentState()
|
|
25
|
+
if (cancel?.current) return
|
|
26
|
+
|
|
27
|
+
// Returning from Google redirect — restore state and authenticate
|
|
28
|
+
if (hasState) {
|
|
29
|
+
await control.restore()
|
|
30
|
+
await control.cleanUpState()
|
|
31
|
+
|
|
32
|
+
const url = new URL(window.location.href)
|
|
33
|
+
const code = url.searchParams.get('code')
|
|
34
|
+
|
|
35
|
+
if (code != null) {
|
|
36
|
+
const auth: AuthCredentials = buildCallbackCredentials(
|
|
37
|
+
url.searchParams.toString(),
|
|
38
|
+
type,
|
|
39
|
+
control.allowance?.challenge ?? '',
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
const token = await control.authenticate(auth)
|
|
43
|
+
|
|
44
|
+
if (token.token !== '') {
|
|
45
|
+
const authService = context.service<AuthService>(AUTH_SERVICE)
|
|
46
|
+
await authService.authenticate(token)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Navigate to app root after successful authentication
|
|
50
|
+
const [homeUrl] = await context.module<Module<string>>(HOME).call({ full: true }) ?? []
|
|
51
|
+
window.location.href = homeUrl ?? window.location.origin
|
|
52
|
+
|
|
53
|
+
return
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Initial request — ask server for Google auth URL
|
|
58
|
+
const [source] = await context.module<Module<string>>(CAUTHEN_AUTHEN_TYPED).call({
|
|
59
|
+
full: true, params: { type }
|
|
60
|
+
}) ?? []
|
|
61
|
+
await control.requestAllowence({ type, source: source ?? '' })
|
|
62
|
+
break
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
case AuthenticationStage.Authenticate: {
|
|
66
|
+
if (cancel?.current) return
|
|
67
|
+
|
|
68
|
+
if (control.allowance?.challenge != null) {
|
|
69
|
+
// The server wraps challenge as "source:googleUrl" — extract the URL part
|
|
70
|
+
const [source] = await context.module<Module<string>>(CAUTHEN_AUTHEN_TYPED).call({
|
|
71
|
+
full: true, params: { type }
|
|
72
|
+
}) ?? []
|
|
73
|
+
const url = extractGoogleUrl(control.allowance.challenge, source ?? '')
|
|
74
|
+
|
|
75
|
+
// Persist control state before redirect
|
|
76
|
+
await control.persist()
|
|
77
|
+
|
|
78
|
+
// Redirect to Google
|
|
79
|
+
document.location.href = url
|
|
80
|
+
}
|
|
81
|
+
break
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}, [type, stage])
|
|
85
|
+
|
|
86
|
+
if (Renderer == null) {
|
|
87
|
+
throw new SyntaxError('Renderer is not defined for Google plugin')
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return <Renderer type={type} stage={stage} control={control} params={{}} />
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
Renderer: () => <Progress />
|
|
94
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helpers extracted from the Google client plugin for unit-testability.
|
|
3
|
+
* These perform the URL/challenge processing logic that doesn't depend on React.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { EnvelopeKind, makeEnvelopeModel } from '@owlmeans/basic-envelope'
|
|
7
|
+
import { AUTH_SCOPE, AuthRole } from '@owlmeans/auth'
|
|
8
|
+
import type { AuthCredentials } from '@owlmeans/auth'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Extract the Google auth URL from a signed challenge envelope message.
|
|
12
|
+
* The server wraps the challenge as "source:googleUrl" — this strips the source prefix.
|
|
13
|
+
* Also handles raw Google URLs (rolling deployment compatibility).
|
|
14
|
+
*/
|
|
15
|
+
export const extractGoogleUrl = (envelopeChallenge: string, sourcePrefix: string): string => {
|
|
16
|
+
const envelope = makeEnvelopeModel(envelopeChallenge, EnvelopeKind.Wrap)
|
|
17
|
+
const msg = envelope.message<string>(true)
|
|
18
|
+
|
|
19
|
+
if (msg.startsWith(sourcePrefix + ':')) {
|
|
20
|
+
return msg.slice(sourcePrefix.length + 1)
|
|
21
|
+
}
|
|
22
|
+
return msg
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Build AuthCredentials from the Google callback URL query params.
|
|
27
|
+
*/
|
|
28
|
+
export const buildCallbackCredentials = (
|
|
29
|
+
queryString: string,
|
|
30
|
+
type: string,
|
|
31
|
+
challenge: string,
|
|
32
|
+
): AuthCredentials => ({
|
|
33
|
+
type,
|
|
34
|
+
challenge,
|
|
35
|
+
credential: queryString,
|
|
36
|
+
role: AuthRole.User,
|
|
37
|
+
userId: 'code',
|
|
38
|
+
scopes: [AUTH_SCOPE],
|
|
39
|
+
})
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
import { plugins as authPlugins } from '@owlmeans/client-auth/manager'
|
|
3
|
-
import { OIDC_CLIENT_AUTH } from '@owlmeans/oidc'
|
|
3
|
+
import { OIDC_CLIENT_AUTH, GOOGLE_CLIENT_AUTH } from '@owlmeans/oidc'
|
|
4
4
|
import { oidcClientPlugin } from './oidc-client.js'
|
|
5
|
+
import { googleClientPlugin } from './google-client.js'
|
|
5
6
|
|
|
6
7
|
authPlugins[OIDC_CLIENT_AUTH] = oidcClientPlugin
|
|
8
|
+
authPlugins[GOOGLE_CLIENT_AUTH] = googleClientPlugin
|
|
7
9
|
|
|
8
10
|
export const plugins = authPlugins
|
|
@@ -4,7 +4,7 @@ import { AUTH_SCOPE, AuthenticationStage, AuthManagerError, AuthRole } from '@ow
|
|
|
4
4
|
import type { AuthCredentials } from '@owlmeans/auth'
|
|
5
5
|
import { OIDC_CLIENT_AUTH } from '@owlmeans/oidc'
|
|
6
6
|
import { useEffect } from 'react'
|
|
7
|
-
import
|
|
7
|
+
import { Progress } from '@/components/ui/progress'
|
|
8
8
|
import { EnvelopeKind, makeEnvelopeModel } from '@owlmeans/basic-envelope'
|
|
9
9
|
import type { Config, Context, OidcAuthService } from '../../types.js'
|
|
10
10
|
import { useContext } from '@owlmeans/web-client'
|
|
@@ -67,8 +67,11 @@ export const oidcClientPlugin: AuthenticationPlugin = {
|
|
|
67
67
|
const oidc = context.service<OidcAuthService>(DEFAULT_ALIAS)
|
|
68
68
|
|
|
69
69
|
// @TODO we need to provide an identity provider client as entityId here for flexibel usage
|
|
70
|
+
const flow = await control.flow()
|
|
71
|
+
const state = await flow?.state()
|
|
70
72
|
const _source = await oidc.proceedToRedirectUrl({
|
|
71
73
|
purpose: control.source as OidcAuthPurposes ?? OidcAuthPurposes.Unknown,
|
|
74
|
+
simplified: state?.payload().simplified as string,
|
|
72
75
|
uid: 'uid' in module.params ? `${module.params.uid}` : undefined,
|
|
73
76
|
alias: module.alias
|
|
74
77
|
})
|
|
@@ -90,6 +93,7 @@ export const oidcClientPlugin: AuthenticationPlugin = {
|
|
|
90
93
|
const envelope = makeEnvelopeModel(control.allowance?.challenge, EnvelopeKind.Wrap)
|
|
91
94
|
const challenge = envelope.message<string>(true)
|
|
92
95
|
const parts = challenge.split(':http')
|
|
96
|
+
// This thing includes url with flow state so the OIDC redirect it back a correct way
|
|
93
97
|
const url = 'http' + parts[1]
|
|
94
98
|
|
|
95
99
|
// 2. Include additional parameters (control state with allowance to flow state)
|
|
@@ -110,5 +114,5 @@ export const oidcClientPlugin: AuthenticationPlugin = {
|
|
|
110
114
|
return <Renderer type={type} stage={stage} control={control} params={module.params} />
|
|
111
115
|
},
|
|
112
116
|
|
|
113
|
-
Renderer: () => <
|
|
117
|
+
Renderer: () => <Progress />
|
|
114
118
|
}
|
package/src/guard.ts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
+
import { DISPATCHER } from '@owlmeans/auth'
|
|
2
|
+
import { handler } from '@owlmeans/client'
|
|
3
|
+
import type { CommonEntrypoint } from '@owlmeans/entrypoint'
|
|
1
4
|
import type { OidcGuardOptions } from '@owlmeans/oidc'
|
|
2
|
-
import type { Config, Context } from './types.js'
|
|
3
|
-
import type { CommonModule } from '@owlmeans/module'
|
|
4
5
|
import {
|
|
5
6
|
appendOidcGuard as appendBasicOidcGuard,
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
DISPATCHER_OIDC, DISPATCHER_OIDC_INIT,
|
|
8
|
+
setupOidcGuard as setupBasicOidcGuard
|
|
8
9
|
} from '@owlmeans/oidc'
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { handler } from '@owlmeans/client'
|
|
10
|
+
import type { ParametrisedProps } from '@owlmeans/web-client'
|
|
11
|
+
import { elevate, parametriseDispatcher } from '@owlmeans/web-client'
|
|
12
12
|
import { Dispatcher } from './components/dispatcher.js'
|
|
13
13
|
import { makeOidcAuthService } from './service.js'
|
|
14
|
+
import type { Config, Context } from './types.js'
|
|
14
15
|
|
|
15
16
|
export const appendOidcGuard = <C extends Config, T extends Context<C>>(
|
|
16
17
|
context: T, opts?: OidcGuardOptions
|
|
@@ -18,14 +19,16 @@ export const appendOidcGuard = <C extends Config, T extends Context<C>>(
|
|
|
18
19
|
context.registerService(makeOidcAuthService())
|
|
19
20
|
|
|
20
21
|
const ctx = appendBasicOidcGuard<C, T>(context, opts)
|
|
21
|
-
|
|
22
|
+
|
|
22
23
|
return ctx
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
export const setupOidcGuard = (modules:
|
|
26
|
+
export const setupOidcGuard = (modules: CommonEntrypoint[], coguards?: string | string[], extras?: Partial<ParametrisedProps>) => {
|
|
27
|
+
const DispatcherCom = extras ? parametriseDispatcher(extras, Dispatcher) : Dispatcher
|
|
28
|
+
|
|
26
29
|
setupBasicOidcGuard(modules, coguards)
|
|
27
30
|
|
|
28
31
|
elevate(modules, DISPATCHER_OIDC_INIT)
|
|
29
32
|
elevate(modules, DISPATCHER_OIDC)
|
|
30
|
-
elevate(modules, DISPATCHER, handler(
|
|
33
|
+
elevate(modules, DISPATCHER, handler(DispatcherCom), { force: true })
|
|
31
34
|
}
|
package/src/service.ts
CHANGED
|
@@ -72,8 +72,12 @@ export const makeOidcAuthService = (alias: string = DEFAULT_ALIAS): OidcAuthServ
|
|
|
72
72
|
|
|
73
73
|
const ctx = service.assertCtx<Config, Context>()
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
let [redirectTo] = await ctx.module<Module<string>>(DISPATCHER_OIDC_INIT)
|
|
76
76
|
.call({ body: params })
|
|
77
|
+
|
|
78
|
+
if (flow.payload().simplified === 'true') {
|
|
79
|
+
redirectTo += '&simplified=true'
|
|
80
|
+
}
|
|
77
81
|
|
|
78
82
|
const context = service.assertCtx<Config, Context>()
|
|
79
83
|
await store(context).save({ id: storeKey, authUrl: redirectTo })
|
|
@@ -91,12 +95,18 @@ export const makeOidcAuthService = (alias: string = DEFAULT_ALIAS): OidcAuthServ
|
|
|
91
95
|
}
|
|
92
96
|
|
|
93
97
|
const authorityTransition = flowModel.next()
|
|
94
|
-
flowModel.transit(authorityTransition.transition, true, {
|
|
98
|
+
flowModel.transit(authorityTransition.transition, true, {
|
|
99
|
+
purpose: extras.purpose,
|
|
100
|
+
simplified: extras.simplified,
|
|
101
|
+
})
|
|
95
102
|
|
|
96
103
|
// @TODO I'm not sure that this dirty hack is a correct approach
|
|
97
104
|
if (extras.alias === HOME) {
|
|
98
105
|
const redirectTransition = flowModel.next()
|
|
99
|
-
flowModel.transit(redirectTransition.transition, true, {
|
|
106
|
+
flowModel.transit(redirectTransition.transition, true, {
|
|
107
|
+
purpose: extras.purpose,
|
|
108
|
+
simplified: extras.simplified
|
|
109
|
+
})
|
|
100
110
|
}
|
|
101
111
|
|
|
102
112
|
const redirectUrl = await flow.proceed({ params: { uid: extras.uid } }, true)
|
package/src/types.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { OIDCAuthInitParams, WithSharedConfig } from '@owlmeans/oidc'
|
|
|
4
4
|
import type { OidcAuthPurposes } from './consts.js'
|
|
5
5
|
import type { FlowModel, FlowPayload } from '@owlmeans/flow'
|
|
6
6
|
import type { ResourceRecord } from '@owlmeans/resource'
|
|
7
|
+
import type { AuthToken } from '@owlmeans/auth'
|
|
7
8
|
|
|
8
9
|
export interface OidcAuthService extends InitializedService {
|
|
9
10
|
dispatch: (params: Record<string, string>) => Promise<boolean>
|
|
@@ -19,10 +20,16 @@ export interface OidcAuthService extends InitializedService {
|
|
|
19
20
|
|
|
20
21
|
export interface OidcAuthRedirectExtras extends FlowPayload {
|
|
21
22
|
purpose: OidcAuthPurposes
|
|
23
|
+
simplified?: string
|
|
22
24
|
uid?: string
|
|
23
25
|
alias?: string
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
export interface OidcPostAuthPayload extends FlowPayload , AuthToken {
|
|
29
|
+
purpose: OidcAuthPurposes
|
|
30
|
+
simplified?: string
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
export interface Config extends AppConfig, WithSharedConfig { }
|
|
27
34
|
|
|
28
35
|
export interface Context<C extends Config = Config> extends AppContext<C> { }
|
package/tests/context.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AppType, Layer, makeBasicContext } from '@owlmeans/context'
|
|
2
|
+
import type { BasicConfig, BasicContext } from '@owlmeans/context'
|
|
3
|
+
|
|
4
|
+
export const makeTestContext = () => {
|
|
5
|
+
const cfg: BasicConfig = {
|
|
6
|
+
ready: false,
|
|
7
|
+
service: 'web-oidc-rp-tests',
|
|
8
|
+
layer: Layer.Application,
|
|
9
|
+
type: AppType.Frontend,
|
|
10
|
+
services: {},
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const context = makeBasicContext(cfg) as BasicContext<BasicConfig>
|
|
14
|
+
|
|
15
|
+
return context
|
|
16
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { describe, test, expect } from 'bun:test'
|
|
2
|
+
import { extractGoogleUrl, buildCallbackCredentials } from '../src/auth/plugins/helpers.js'
|
|
3
|
+
import { AUTH_SCOPE, AuthRole } from '@owlmeans/auth'
|
|
4
|
+
import { makeFixtureKeyPair, signMockEnvelope } from '@owlmeans/test-auth'
|
|
5
|
+
import { EnvelopeKind } from '@owlmeans/basic-envelope'
|
|
6
|
+
|
|
7
|
+
describe('@owlmeans/web-oidc-rp — extractGoogleUrl', () => {
|
|
8
|
+
test('strips source prefix from envelope message', async () => {
|
|
9
|
+
const kp = makeFixtureKeyPair('web-oidc-test')
|
|
10
|
+
const googleUrl = 'https://accounts.google.com/o/oauth2/v2/auth?client_id=abc&state=xyz'
|
|
11
|
+
const source = 'https://example.com/auth'
|
|
12
|
+
const challengeMsg = `${source}:${googleUrl}`
|
|
13
|
+
// Create a signed envelope wrapping the prefixed URL
|
|
14
|
+
const envelope = await signMockEnvelope(challengeMsg, 'string', EnvelopeKind.Wrap, kp)
|
|
15
|
+
|
|
16
|
+
const result = extractGoogleUrl(envelope, source)
|
|
17
|
+
|
|
18
|
+
expect(result).toBe(googleUrl)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
test('handles raw URL without source prefix', async () => {
|
|
22
|
+
const kp = makeFixtureKeyPair('web-oidc-test-2')
|
|
23
|
+
const googleUrl = 'https://accounts.google.com/o/oauth2/v2/auth?client_id=abc&state=xyz'
|
|
24
|
+
const envelope = await signMockEnvelope(googleUrl, 'string', EnvelopeKind.Wrap, kp)
|
|
25
|
+
|
|
26
|
+
const result = extractGoogleUrl(envelope, 'https://different.example.com')
|
|
27
|
+
|
|
28
|
+
expect(result).toBe(googleUrl)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
test('handles empty source prefix', async () => {
|
|
32
|
+
const kp = makeFixtureKeyPair('web-oidc-test-3')
|
|
33
|
+
const googleUrl = 'https://accounts.google.com/o/oauth2/v2/auth?client_id=abc'
|
|
34
|
+
const envelope = await signMockEnvelope(googleUrl, 'string', EnvelopeKind.Wrap, kp)
|
|
35
|
+
|
|
36
|
+
const result = extractGoogleUrl(envelope, '')
|
|
37
|
+
|
|
38
|
+
expect(result).toBe(googleUrl)
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
describe('@owlmeans/web-oidc-rp — buildCallbackCredentials', () => {
|
|
43
|
+
test('builds AuthCredentials from query params', () => {
|
|
44
|
+
const queryString = 'code=4/0abc123&state=test-state-xyz&scope=openid+email'
|
|
45
|
+
const type = 'google-oauth'
|
|
46
|
+
const challenge = 'stored-challenge-value'
|
|
47
|
+
|
|
48
|
+
const creds = buildCallbackCredentials(queryString, type, challenge)
|
|
49
|
+
|
|
50
|
+
expect(creds.type).toBe('google-oauth')
|
|
51
|
+
expect(creds.challenge).toBe('stored-challenge-value')
|
|
52
|
+
expect(creds.credential).toBe(queryString)
|
|
53
|
+
expect(creds.role).toBe(AuthRole.User)
|
|
54
|
+
expect(creds.userId).toBe('code')
|
|
55
|
+
expect(creds.scopes).toEqual([AUTH_SCOPE])
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
test('works with empty challenge', () => {
|
|
59
|
+
const creds = buildCallbackCredentials('code=x&state=y', 'google-oauth', '')
|
|
60
|
+
|
|
61
|
+
expect(creds.challenge).toBe('')
|
|
62
|
+
expect(creds.credential).toBe('code=x&state=y')
|
|
63
|
+
})
|
|
64
|
+
})
|
package/tsconfig.json
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"extends": [
|
|
3
|
-
"
|
|
4
|
-
"
|
|
3
|
+
"@owlmeans/dep-config/tsconfig.base.json",
|
|
4
|
+
"@owlmeans/dep-config/tsconfig.react.json"
|
|
5
5
|
],
|
|
6
6
|
"compilerOptions": {
|
|
7
|
-
"
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
"paths": {
|
|
8
|
+
"@/*": ["./src/@/*"]
|
|
9
|
+
},
|
|
10
|
+
"rootDir": "./src/",
|
|
11
|
+
"outDir": "./build/"
|
|
10
12
|
},
|
|
11
|
-
"exclude": [
|
|
12
|
-
|
|
13
|
-
"./build/**/*",
|
|
14
|
-
"./*.ts"
|
|
15
|
-
]
|
|
16
|
-
}
|
|
13
|
+
"exclude": ["./dist/**/*", "./build/**/*", "./tests/**/*", "./*.ts"]
|
|
14
|
+
}
|