Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
8643453
First round of adaption
corbadoman Jan 31, 2025
ddca815
First round of adaption
corbadoman Jan 31, 2025
3555407
Third round of adaption
corbadoman Jan 31, 2025
233f4fb
Bugfixing
corbadoman Jan 31, 2025
b531a9d
Bugfixing
corbadoman Jan 31, 2025
caee9ae
Updated OpenAPI public FAPI v2 client
corbadoman Jan 31, 2025
581027a
Forth round of adaption
corbadoman Jan 31, 2025
b955c35
Adapted react
corbadoman Jan 31, 2025
700fb8b
Adapted NextJS example
corbadoman Jan 31, 2025
5a7a940
Removed more old code, updated public FAPI v2 OpenAPI spec once again…
corbadoman Feb 1, 2025
da3c680
Regenerated OpenAPI client
corbadoman Feb 1, 2025
4de5f4e
Removed old auth model (was using public FAPI v1)
corbadoman Feb 1, 2025
1e9c56f
Adapted code to new session-token cookie config
corbadoman Feb 1, 2025
235d783
Added refresh-token documentation
corbadoman Feb 1, 2025
8da0df7
Morerefresh-token documentation
corbadoman Feb 1, 2025
bea7979
Cleaning up FAPI URL configuration
corbadoman Feb 1, 2025
785abe4
Cleaning up FAPI URL configuration
corbadoman Feb 1, 2025
b414b4b
Fixed trailing slash validation of FAPI url
corbadoman Feb 3, 2025
63cedc9
Error handling debugging
corbadoman Feb 3, 2025
7b67d02
fix react playground
lukaskratzel Feb 6, 2025
a25eb03
fmt
lukaskratzel Feb 6, 2025
16271ad
PR feedback
corbadoman Feb 6, 2025
7ed656b
Some more longSession => refreshToken renames
corbadoman Feb 6, 2025
3edd735
Made frontendApi prop optional
corbadoman Feb 6, 2025
25bf2cd
Bugfixing
corbadoman Feb 6, 2025
02a79a1
Small improvement
corbadoman Feb 6, 2025
d422904
Fixed environment variables
corbadoman Feb 6, 2025
6d7ef59
Changed it back to frontendApiUrlSuffix
corbadoman Feb 6, 2025
f58c246
More backporting
corbadoman Feb 7, 2025
8349edd
More backporting
corbadoman Feb 7, 2025
2d0e5f7
First round of adaption
corbadoman Jan 31, 2025
8de8450
First round of adaption
corbadoman Jan 31, 2025
3cab062
Third round of adaption
corbadoman Jan 31, 2025
8a90a30
Bugfixing
corbadoman Jan 31, 2025
f3b3a2d
Bugfixing
corbadoman Jan 31, 2025
7c4a79b
Updated OpenAPI public FAPI v2 client
corbadoman Jan 31, 2025
d9f74b3
Forth round of adaption
corbadoman Jan 31, 2025
7e89ade
Adapted react
corbadoman Jan 31, 2025
1dd7419
Adapted NextJS example
corbadoman Jan 31, 2025
f654d0f
Removed more old code, updated public FAPI v2 OpenAPI spec once again…
corbadoman Feb 1, 2025
4952770
Regenerated OpenAPI client
corbadoman Feb 1, 2025
9609aaa
Removed old auth model (was using public FAPI v1)
corbadoman Feb 1, 2025
5e8bbcc
Adapted code to new session-token cookie config
corbadoman Feb 1, 2025
59ad73a
Added refresh-token documentation
corbadoman Feb 1, 2025
65072d9
Morerefresh-token documentation
corbadoman Feb 1, 2025
e777bb4
Cleaning up FAPI URL configuration
corbadoman Feb 1, 2025
d00c6ea
Cleaning up FAPI URL configuration
corbadoman Feb 1, 2025
12f4cc8
Fixed trailing slash validation of FAPI url
corbadoman Feb 3, 2025
a140184
Error handling debugging
corbadoman Feb 3, 2025
b7a3c9e
fix react playground
lukaskratzel Feb 6, 2025
d9c0223
fmt
lukaskratzel Feb 6, 2025
2b7c6a2
PR feedback
corbadoman Feb 6, 2025
a19940f
Some more longSession => refreshToken renames
corbadoman Feb 6, 2025
5e6d25c
Made frontendApi prop optional
corbadoman Feb 6, 2025
d97b9ff
Bugfixing
corbadoman Feb 6, 2025
1ba0585
Small improvement
corbadoman Feb 6, 2025
dfd9bb0
Fixed environment variables
corbadoman Feb 6, 2025
1002065
Changed it back to frontendApiUrlSuffix
corbadoman Feb 6, 2025
fa2e7bf
More backporting
corbadoman Feb 7, 2025
1d66515
More backporting
corbadoman Feb 7, 2025
0884d82
fmt
lukaskratzel Feb 7, 2025
48491b4
Resolved merge conflicts
corbadoman Feb 7, 2025
b0446e7
Removed .cloud from frontendApiUrlSuffix
corbadoman Feb 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions examples/nextjs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ These are the different pages that you will find in this application:
- `/signup` : Signup component page
- `/dashboard` : The dashboard has three nested routes:
- `/` : User Details page which uses `@corbado/node-sdk` to fetch complete details of the currently logged-in user.
- `/session-details` : this page deserializes the short session and show cases the details stored in the short session.
- `/session-details` : this page deserializes the session-token and show cases the details stored in the session-token.
- `/passkey-list` : this page uses the `@corbado/react`'s `<PasskeyList/>` component to showcase its use

## Points to Note

- When you use a component from `@corbado/react` either a UI component or a Provider component you need to `use client` for client side rendering as the components make use of react contexts.
- For using `<CorbadoProvider />` with NextJS application we need to set `setShortSessionCookie` to true. It's important to set this since Corbado uses refresh tokens to keep the user logged in and by storing short session cookies, the user will be able to stay logged in even if the token is refreshed
3 changes: 0 additions & 3 deletions examples/nextjs/app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ export function Providers({ children }: { children: React.ReactNode }) {
<CorbadoProvider
projectId={process.env.NEXT_PUBLIC_CORBADO_PROJECT_ID!}
darkMode='off'
//it's important to set this since Corbado uses refresh tokens to keep the user logged in
//by storing short session cookies, the user will be able to stay logged in even if the token is refreshed
setShortSessionCookie={true}
>
{children}
</CorbadoProvider>
Expand Down
4 changes: 2 additions & 2 deletions examples/nextjs/app/ui/dashboard/current-user.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import createNodeSDK from '@/app/utils/createNodeSDK';

export default async function CurrentUser() {
const cookieStore = cookies();
const session = cookieStore.get('cbo_short_session');
const sessionTokenCookie = cookieStore.get('cbo_session_token');
const sdk = createNodeSDK();
const currentSessionUser = await sdk.sessions().getCurrentUser(session?.value ?? '');
const currentSessionUser = await sdk.sessions().getCurrentUser(sessionTokenCookie?.value ?? '');
const userResp = await sdk.users().get(currentSessionUser?.getID() ?? '');
const user = userResp.data;
const activeEmail = user.emails.find(email => email.status === 'active');
Expand Down
10 changes: 5 additions & 5 deletions examples/nextjs/app/ui/dashboard/session-details.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { cookies } from 'next/headers';

export default function SessionDetails() {
const cookieStore = cookies();
const session = cookieStore.get('cbo_short_session');
const sessionTokenCookie = cookieStore.get('cbo_session_token');

const decodedShortSession = jwtDecode(session?.value ?? '');
const serializedDecodedShortSession = JSON.stringify(decodedShortSession, null, 2);
const decodedSessionToken = jwtDecode(sessionTokenCookie?.value ?? '');
const serializedDecodedSessionToken = JSON.stringify(decodedSessionToken, null, 2);

return (
<>
<div className='mb-3 mt-3'>
<p>This is your shortSession:</p>
<pre>{serializedDecodedShortSession}</pre>
<p>This is your sessionToken:</p>
<pre>{serializedDecodedSessionToken}</pre>
</div>
</>
);
Expand Down
6 changes: 3 additions & 3 deletions examples/nextjs/app/ui/right-intro-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import Image from 'next/image';

export default async function RightIntroSection() {
const cookieStore = cookies();
const sessionCookie = cookieStore.get('cbo_short_session');
const shortSession = sessionCookie?.value;
const isSessionValid = await validateSession(shortSession);
const sessionTokenCookie = cookieStore.get('cbo_session_token');
const sessionToken = sessionTokenCookie?.value;
const isSessionValid = await validateSession(sessionToken);

if (isSessionValid) {
return (
Expand Down
10 changes: 5 additions & 5 deletions examples/nextjs/app/utils/validateSession.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { jwtDecode } from 'jwt-decode';
import createNodeSDK from './createNodeSDK';

export default async function validateSession(shortSession: string | undefined) {
if (!shortSession) {
export default async function validateSession(sessionToken: string | undefined) {
if (!sessionToken) {
return false;
}

const sdk = createNodeSDK();
const verifiedSession = await sdk.sessions().validateShortSessionValue(shortSession);
const verifiedSession = await sdk.sessions().validateShortSessionValue(sessionToken);

if (!verifiedSession.isAuthenticated()) {
return false;
}

const decodedShortSession = jwtDecode(shortSession);
return !!decodedShortSession.exp && decodedShortSession.exp > Date.now() / 1000;
const decodedSessionToken = jwtDecode(sessionToken);
return !!decodedSessionToken.exp && decodedSessionToken.exp > Date.now() / 1000;
}
6 changes: 3 additions & 3 deletions examples/nextjs/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ export async function middleware(request: NextRequest) {
return NextResponse.next();
}

const cookie = request.cookies.get('cbo_short_session');
const shortSession = cookie?.value;
const isSessionValid = await validateSession(shortSession);
const cookie = request.cookies.get('cbo_session_token');
const sessionToken = cookie?.value;
const isSessionValid = await validateSession(sessionToken);

if (isSessionValid && routes.authPaths.includes(url.pathname)) {
url.pathname = '/dashboard';
Expand Down
6 changes: 0 additions & 6 deletions packages/react/src/contexts/CorbadoSessionContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ const missingImplementation = (): never => {
export interface CorbadoSessionContextProps {
corbadoApp: CorbadoApp | undefined;

/**
* @deprecated Use sessionToken instead
*/
shortSession: string | undefined;

sessionToken: string | undefined;
loading: boolean;
isAuthenticated: boolean;
Expand All @@ -29,7 +24,6 @@ export interface CorbadoSessionContextProps {

export const initialContext: CorbadoSessionContextProps = {
corbadoApp: undefined,
shortSession: undefined,
sessionToken: undefined,
loading: true,
isAuthenticated: false,
Expand Down
11 changes: 4 additions & 7 deletions packages/react/src/contexts/CorbadoSessionProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const CorbadoSessionProvider: FC<CorbadoSessionProviderParams> = ({
const [loading, setLoading] = useState<boolean>(true);
const [user, setUser] = useState<SessionUser | undefined>();
const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
const [shortSession, setShortSession] = useState<string | undefined>();
const [sessionToken, setSessionToken] = useState<string | undefined>();

const init = async () => {
setLoading(true);
Expand All @@ -46,14 +46,14 @@ export const CorbadoSessionProvider: FC<CorbadoSessionProviderParams> = ({
setIsAuthenticated(!!value);
});

const shortSessionSub = corbadoApp.sessionService.shortSessionChanges.subscribe((value: string | undefined) => {
setShortSession(value);
const sessionTokenSub = corbadoApp.sessionService.sessionTokenChanges.subscribe((value: string | undefined) => {
setSessionToken(value);
});

return () => {
userSub.unsubscribe();
authStateSub.unsubscribe();
shortSessionSub.unsubscribe();
sessionTokenSub.unsubscribe();
};
}, []);

Expand Down Expand Up @@ -86,13 +86,10 @@ export const CorbadoSessionProvider: FC<CorbadoSessionProviderParams> = ({
[corbadoApp],
);

const sessionToken = shortSession;

return (
<CorbadoSessionContext.Provider
value={{
corbadoApp,
shortSession,
sessionToken,
loading,
user,
Expand Down
2 changes: 1 addition & 1 deletion packages/shared-ui/src/flowHandler/processHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ export class ProcessHandler {
this.#corbadoApp.authProcessService.clearProcess();
this.#corbadoApp.authProcessService.dropLastIdentifier(data.passkeyOperation);
this.#currentBlock = null;
this.#corbadoApp.sessionService.setSession(data.shortSession, data.longSession);
this.#corbadoApp.sessionService.setSession(data.sessionToken, data.refreshToken);

this.#postProcess();
}
Expand Down
3 changes: 0 additions & 3 deletions packages/types/src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ export interface Paging {
export interface CorbadoAppParams {
projectId: string;
apiTimeout?: number;
// deprecated (no longer needed, Corbado backend sets this value automatically)
frontendApiUrl?: string;
frontendApiUrlSuffix?: string;
isDevMode?: boolean;
setShortSessionCookie?: boolean;
isPreviewMode?: boolean;
}
38 changes: 37 additions & 1 deletion packages/web-core/openapi/spec_v2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,8 @@ components:
type: boolean
shortSessionCookieConfig:
$ref: '#/components/schemas/shortSessionCookieConfig'
sessionTokenCookieConfig:
$ref: '#/components/schemas/sessionTokenCookieConfig'
frontendApiUrl:
type: string

Expand Down Expand Up @@ -1170,9 +1172,13 @@ components:
type: object
required:
- shortSession
- sessionToken
properties:
shortSession:
type: string
deprecated: true
sessionToken:
type: string

mePasskeyDeleteRsp:
type: object
Expand Down Expand Up @@ -1592,6 +1598,28 @@ components:
type: boolean

shortSessionCookieConfig:
type: object
deprecated: true
required:
- domain
- secure
- sameSite
- path
- lifetimeSeconds
properties:
domain:
type: string
secure:
type: boolean
sameSite:
type: string
enum: [ 'lax', 'strict', 'none' ]
path:
type: string
lifetimeSeconds:
type: integer

sessionTokenCookieConfig:
type: object
required:
- domain
Expand Down Expand Up @@ -1820,14 +1848,22 @@ components:
required:
- blockType
- shortSession
- sessionToken
properties:
blockType:
type: string
longSession:
type: string
description: Only given when project environment is dev
deprecated: true
description: This is only set if the project environment is set to 'dev'. If set the UI components will set the longSession in local storage because the cookie dropping will not work in Safari for example ("third-party cookie").
refreshToken:
type: string
description: This is only set if the project environment is set to 'dev'. If set the UI components will set the longSession in local storage because the cookie dropping will not work in Safari for example ("third-party cookie").
shortSession:
type: string
deprecated: true
sessionToken:
type: string
passkeyOperation:
$ref: '#/components/schemas/passkeyOperation'

Expand Down
76 changes: 75 additions & 1 deletion packages/web-core/src/api/v2/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -855,17 +855,31 @@ export interface GeneralBlockCompleted {
*/
'blockType': string;
/**
* Only given when project environment is dev
* This is only set if the project environment is set to \'dev\'. If set the UI components will set the longSession in local storage because the cookie dropping will not work in Safari for example (\"third-party cookie\").
* @type {string}
* @memberof GeneralBlockCompleted
* @deprecated
*/
'longSession'?: string;
/**
* This is only set if the project environment is set to \'dev\'. If set the UI components will set the longSession in local storage because the cookie dropping will not work in Safari for example (\"third-party cookie\").
* @type {string}
* @memberof GeneralBlockCompleted
*/
'refreshToken'?: string;
/**
*
* @type {string}
* @memberof GeneralBlockCompleted
* @deprecated
*/
'shortSession': string;
/**
*
* @type {string}
* @memberof GeneralBlockCompleted
*/
'sessionToken': string;
/**
*
* @type {PasskeyOperation}
Expand Down Expand Up @@ -1644,8 +1658,15 @@ export interface MeRefreshRsp {
*
* @type {string}
* @memberof MeRefreshRsp
* @deprecated
*/
'shortSession': string;
/**
*
* @type {string}
* @memberof MeRefreshRsp
*/
'sessionToken': string;
}
/**
*
Expand Down Expand Up @@ -2163,15 +2184,68 @@ export interface SessionConfigRsp {
*
* @type {ShortSessionCookieConfig}
* @memberof SessionConfigRsp
* @deprecated
*/
'shortSessionCookieConfig'?: ShortSessionCookieConfig;
/**
*
* @type {SessionTokenCookieConfig}
* @memberof SessionConfigRsp
*/
'sessionTokenCookieConfig'?: SessionTokenCookieConfig;
/**
*
* @type {string}
* @memberof SessionConfigRsp
*/
'frontendApiUrl'?: string;
}
/**
*
* @export
* @interface SessionTokenCookieConfig
*/
export interface SessionTokenCookieConfig {
/**
*
* @type {string}
* @memberof SessionTokenCookieConfig
*/
'domain': string;
/**
*
* @type {boolean}
* @memberof SessionTokenCookieConfig
*/
'secure': boolean;
/**
*
* @type {string}
* @memberof SessionTokenCookieConfig
*/
'sameSite': SessionTokenCookieConfigSameSiteEnum;
/**
*
* @type {string}
* @memberof SessionTokenCookieConfig
*/
'path': string;
/**
*
* @type {number}
* @memberof SessionTokenCookieConfig
*/
'lifetimeSeconds': number;
}

export const SessionTokenCookieConfigSameSiteEnum = {
Lax: 'lax',
Strict: 'strict',
None: 'none'
} as const;

export type SessionTokenCookieConfigSameSiteEnum = typeof SessionTokenCookieConfigSameSiteEnum[keyof typeof SessionTokenCookieConfigSameSiteEnum];

/**
*
* @export
Expand Down
Loading
Loading