Skip to content

Commit 3da9e5d

Browse files
committed
feat(provider): ✨ Added AWS Cognito provider
1 parent 8605ba4 commit 3da9e5d

File tree

7 files changed

+116
-14
lines changed

7 files changed

+116
-14
lines changed

playground/.env.example

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,8 @@ NUXT_OIDC_PROVIDERS_GITHUB_CLIENT_ID=
2525
NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_SECRET=
2626
NUXT_OIDC_PROVIDERS_KEYCLOAK_CLIENT_ID=
2727
NUXT_OIDC_PROVIDERS_KEYCLOAK_BASE_URL=
28+
# COGNITO PROVIDER CONFIG
29+
NUXT_OIDC_PROVIDERS_COGNITO_CLIENT_ID=
30+
NUXT_OIDC_PROVIDERS_COGNITO_CLIENT_SECRET=
31+
NUXT_OIDC_PROVIDERS_COGNITO_BASE_URL=
32+
NUXT_OIDC_PROVIDERS_COGNITO_OPEN_ID_CONFIGURATION=

playground/composables/useProviders.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ export function useProviders(currentProvider: string) {
2626
disabled: Boolean(currentProvider === 'keycloak'),
2727
icon: 'i-simple-icons-cncf',
2828
},
29+
{
30+
label: 'AWS Cognito',
31+
name: 'cognito',
32+
disabled: Boolean(currentProvider === 'cognito'),
33+
icon: 'i-simple-icons-amazoncognito',
34+
},
2935
{
3036
label: 'Generic OIDC',
3137
name: 'oidc',

playground/nuxt.config.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,15 @@ export default defineNuxtConfig({
6767
exposeAccessToken: true,
6868
userNameClaim: 'preferred_username',
6969
},
70+
cognito: {
71+
clientId: '',
72+
redirectUri: 'http://localhost:3000/auth/cognito/callback',
73+
clientSecret: '',
74+
scope: ['openid', 'email', 'profile'],
75+
logoutRedirectUri: 'https://google.com',
76+
baseUrl: '',
77+
openIdConfiguration: '',
78+
}
7079
},
7180
session: {
7281
expirationCheck: true,

src/module.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,46 @@ export default defineNuxtModule<ModuleOptions>({
165165
if (baseUrl) {
166166
(options.providers[provider] as OidcProviderConfig).authorizationUrl = generateProviderUrl(baseUrl as string, providerPresets[provider].authorizationUrl);
167167
(options.providers[provider] as OidcProviderConfig).tokenUrl = generateProviderUrl(baseUrl as string, providerPresets[provider].tokenUrl);
168+
(options.providers[provider] as OidcProviderConfig).logoutUrl = generateProviderUrl(baseUrl as string, providerPresets[provider].logoutUrl);
168169
(options.providers[provider] as OidcProviderConfig).userInfoUrl = generateProviderUrl(baseUrl as string, providerPresets[provider].userInfoUrl)
169170
}
170171

172+
// Replace clientId in additionalAuthParameters
173+
if (providerPresets[provider].additionalAuthParameters) {
174+
const entry = providerPresets[provider].additionalAuthParameters as Record<string, string>
175+
Object.keys(entry).forEach((param) => {
176+
if ((entry[param] as string).includes('{clientId}')) {
177+
if (!(options.providers[provider] as OidcProviderConfig).additionalAuthParameters)
178+
(options.providers[provider] as OidcProviderConfig).additionalAuthParameters = {};
179+
(options.providers[provider] as OidcProviderConfig).additionalAuthParameters![param] = entry[param].replace('{clientId}', (options.providers[provider] as OidcProviderConfig).clientId || process.env[`NUXT_OIDC_PROVIDERS_${provider.toUpperCase()}_CLIENT_ID`] || '')
180+
}
181+
})
182+
}
183+
184+
// Replace clientId in additionalTokenParameters
185+
if (providerPresets[provider].additionalTokenParameters) {
186+
const entry = providerPresets[provider].additionalTokenParameters as Record<string, string>
187+
Object.keys(entry).forEach((param) => {
188+
if ((entry[param] as string).includes('{clientId}')) {
189+
if (!(options.providers[provider] as OidcProviderConfig).additionalTokenParameters)
190+
(options.providers[provider] as OidcProviderConfig).additionalTokenParameters = {};
191+
(options.providers[provider] as OidcProviderConfig).additionalTokenParameters![param] = entry[param].replace('{clientId}', (options.providers[provider] as OidcProviderConfig).clientId || process.env[`NUXT_OIDC_PROVIDERS_${provider.toUpperCase()}_CLIENT_ID`] || '')
192+
}
193+
})
194+
}
195+
196+
// Replace clientId in additionalLogoutParameters
197+
if (providerPresets[provider].additionalLogoutParameters) {
198+
const entry = providerPresets[provider].additionalLogoutParameters as Record<string, string>
199+
Object.keys(entry).forEach((param) => {
200+
if ((entry[param] as string).includes('{clientId}')) {
201+
if (!(options.providers[provider] as OidcProviderConfig).additionalLogoutParameters)
202+
(options.providers[provider] as OidcProviderConfig).additionalLogoutParameters = {};
203+
(options.providers[provider] as OidcProviderConfig).additionalLogoutParameters![param] = entry[param].replace('{clientId}', (options.providers[provider] as OidcProviderConfig).clientId || process.env[`NUXT_OIDC_PROVIDERS_${provider.toUpperCase()}_CLIENT_ID`] || '')
204+
}
205+
})
206+
}
207+
171208
// Add login handler
172209
addServerHandler({
173210
handler: resolve('./runtime/server/handler/login.get'),

src/runtime/providers/cognito.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { ofetch } from 'ofetch'
2+
import { normalizeURL, withHttps, withoutTrailingSlash } from 'ufo'
3+
import { defineOidcProvider } from '../server/utils/provider'
4+
5+
interface CognitoProviderConfig {
6+
connection?: string
7+
organization?: string
8+
invitation?: string
9+
loginHint?: string
10+
}
11+
12+
type CognitoRequiredFields = 'baseUrl' | 'clientId' | 'clientSecret' | 'logoutRedirectUri' | 'openIdConfiguration'
13+
14+
export const cognito = defineOidcProvider<CognitoProviderConfig, CognitoRequiredFields>({
15+
userNameClaim: 'username',
16+
responseType: 'code',
17+
tokenRequestType: 'form-urlencoded',
18+
authenticationScheme: 'header',
19+
userInfoUrl: 'oauth2/userInfo',
20+
grantType: 'authorization_code',
21+
scope: ['openid'],
22+
pkce: true,
23+
state: true,
24+
nonce: true,
25+
scopeInTokenRequest: false,
26+
callbackRedirectUrl: '/',
27+
authorizationUrl: 'oauth2/authorize',
28+
tokenUrl: 'oauth2/token',
29+
logoutUrl: 'logout',
30+
requiredProperties: [
31+
'baseUrl',
32+
'clientId',
33+
'clientSecret',
34+
'authorizationUrl',
35+
'tokenUrl',
36+
'logoutRedirectUri',
37+
'openIdConfiguration',
38+
],
39+
validateAccessToken: true,
40+
validateIdToken: true,
41+
additionalLogoutParameters: {
42+
clientId: '{clientId}',
43+
},
44+
sessionConfiguration: {
45+
expirationCheck: true,
46+
automaticRefresh: true,
47+
expirationThreshold: 240,
48+
},
49+
logoutRedirectParameterName: 'logout_uri',
50+
})

src/runtime/providers/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export { apple } from './apple.js'
22
export { auth0 } from './auth0.js'
3+
export { cognito } from './cognito.js'
34
export { entra } from './entra.js'
45
export { github } from './github.js'
56
export { keycloak } from './keycloak.js'

src/runtime/types.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,17 @@ import type * as _PROVIDERS from './providers'
55

66
import type { EncryptedToken, JwtPayload } from './server/utils/security'
77

8-
export type ProviderKeys = 'apple' | 'auth0' | 'entra' | 'github' | 'keycloak' | 'oidc'
8+
export type ProviderKeys = 'apple' | 'auth0' | 'entra' | 'github' | 'keycloak' | 'oidc' | 'cognito'
99
export type ProviderKeysWithDev = ProviderKeys | 'dev'
1010

11-
type Auth0Provider = typeof _PROVIDERS.auth0
12-
type AppleProvider = typeof _PROVIDERS.apple
13-
type EntraProvider = typeof _PROVIDERS.entra
14-
type GithubProvider = typeof _PROVIDERS.github
15-
type KeycloakProvider = typeof _PROVIDERS.keycloak
16-
type OidcProvider = typeof _PROVIDERS.oidc
17-
1811
export interface ProviderConfigs {
19-
auth0: Auth0Provider
20-
apple: AppleProvider
21-
entra: EntraProvider
22-
github: GithubProvider
23-
keycloak: KeycloakProvider
24-
oidc: OidcProvider
12+
auth0: typeof _PROVIDERS.auth0
13+
apple: typeof _PROVIDERS.apple
14+
entra: typeof _PROVIDERS.entra
15+
github: typeof _PROVIDERS.github
16+
keycloak: typeof _PROVIDERS.keycloak
17+
oidc: typeof _PROVIDERS.oidc
18+
cognito: typeof _PROVIDERS.cognito
2519
}
2620

2721
export interface OAuthConfig<UserSession> {

0 commit comments

Comments
 (0)