Skip to content

Commit 15e85cb

Browse files
authored
Use flag for passkey session (#112)
1 parent 7ef9032 commit 15e85cb

File tree

4 files changed

+58
-17
lines changed

4 files changed

+58
-17
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@authsignal/browser",
3-
"version": "1.12.0",
3+
"version": "1.12.1",
44
"type": "module",
55
"main": "dist/index.js",
66
"module": "dist/index.js",

src/api/passkey-api-client.ts

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import {buildHeaders, handleTokenExpired} from "./helpers";
22
import {
33
AddAuthenticatorRequest,
44
AddAuthenticatorResponse,
5+
AuthenticationOptsRequest,
56
AuthenticationOptsResponse,
7+
ChallengeRequest,
68
ChallengeResponse,
79
ErrorResponse,
810
PasskeyAuthenticatorResponse,
@@ -28,16 +30,23 @@ export class PasskeyApiClient {
2830
token,
2931
username,
3032
authenticatorAttachment,
33+
useCookies,
3134
}: {token: string} & RegistrationOptsRequest): Promise<RegistrationOptsResponse | ErrorResponse> {
3235
const body: RegistrationOptsRequest = Boolean(authenticatorAttachment)
3336
? {username, authenticatorAttachment}
3437
: {username};
3538

36-
const response = await fetch(`${this.baseUrl}/client/user-authenticators/passkey/registration-options/web`, {
39+
const url = useCookies
40+
? `${this.baseUrl}/client/user-authenticators/passkey/registration-options/web`
41+
: `${this.baseUrl}/client/user-authenticators/passkey/registration-options`;
42+
43+
const credentials = useCookies ? "include" : "same-origin";
44+
45+
const response = await fetch(url, {
3746
method: "POST",
3847
headers: buildHeaders({token, tenantId: this.tenantId}),
3948
body: JSON.stringify(body),
40-
credentials: "include",
49+
credentials,
4150
});
4251

4352
const responseJson = await response.json();
@@ -47,12 +56,17 @@ export class PasskeyApiClient {
4756
return responseJson;
4857
}
4958

50-
async authenticationOptions({token}: {token?: string}): Promise<AuthenticationOptsResponse | ErrorResponse> {
59+
async authenticationOptions({
60+
token,
61+
useCookies,
62+
}: {
63+
token?: string;
64+
} & AuthenticationOptsRequest): Promise<AuthenticationOptsResponse | ErrorResponse> {
5165
const response = await fetch(`${this.baseUrl}/client/user-authenticators/passkey/authentication-options`, {
5266
method: "POST",
5367
headers: buildHeaders({token, tenantId: this.tenantId}),
5468
body: JSON.stringify({}),
55-
credentials: "include",
69+
credentials: useCookies ? "include" : "same-origin",
5670
});
5771

5872
const responseJson = await response.json();
@@ -81,17 +95,20 @@ export class PasskeyApiClient {
8195
token,
8296
registrationCredential,
8397
conditionalCreate,
98+
challengeId,
99+
useCookies,
84100
}: {token: string} & AddAuthenticatorRequest): Promise<AddAuthenticatorResponse | ErrorResponse> {
85101
const body: AddAuthenticatorRequest = {
86102
registrationCredential,
87103
conditionalCreate,
104+
challengeId,
88105
};
89106

90107
const response = await fetch(`${this.baseUrl}/client/user-authenticators/passkey`, {
91108
method: "POST",
92109
headers: buildHeaders({token, tenantId: this.tenantId}),
93110
body: JSON.stringify(body),
94-
credentials: "include",
111+
credentials: useCookies ? "include" : "same-origin",
95112
});
96113

97114
const responseJson = await response.json();
@@ -105,14 +122,15 @@ export class PasskeyApiClient {
105122
authenticationCredential,
106123
token,
107124
deviceId,
125+
useCookies,
108126
}: {token?: string} & VerifyRequest): Promise<VerifyResponse | ErrorResponse> {
109127
const body: VerifyRequest = {authenticationCredential, deviceId};
110128

111129
const response = await fetch(`${this.baseUrl}/client/verify/passkey`, {
112130
method: "POST",
113131
headers: buildHeaders({token, tenantId: this.tenantId}),
114132
body: JSON.stringify(body),
115-
credentials: "include",
133+
credentials: useCookies ? "include" : "same-origin",
116134
});
117135

118136
const responseJson = await response.json();
@@ -139,14 +157,14 @@ export class PasskeyApiClient {
139157
return response.json();
140158
}
141159

142-
async challenge(action: string): Promise<ChallengeResponse | ErrorResponse> {
143-
const url = `${this.baseUrl}/client/challenge/web`;
160+
async challenge({action, useCookies}: ChallengeRequest): Promise<ChallengeResponse | ErrorResponse> {
161+
const url = useCookies ? `${this.baseUrl}/client/challenge/web` : `${this.baseUrl}/client/challenge`;
144162

145163
const response = await fetch(url, {
146164
method: "POST",
147165
headers: buildHeaders({tenantId: this.tenantId}),
148166
body: JSON.stringify({action}),
149-
credentials: "include",
167+
credentials: useCookies ? "include" : "same-origin",
150168
});
151169

152170
const responseJson = await response.json();

src/api/types/passkey.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,20 +9,29 @@ import {Authenticator} from "./shared";
99
export type RegistrationOptsRequest = {
1010
username?: string;
1111
authenticatorAttachment?: AuthenticatorAttachment | null;
12+
useCookies?: boolean;
1213
};
1314

1415
export type RegistrationOptsResponse = {
15-
challengeId: string;
16+
challengeId?: string;
1617
options: PublicKeyCredentialCreationOptionsJSON;
1718
};
1819

20+
export type AuthenticationOptsRequest = {
21+
challengeId?: string;
22+
useCookies?: boolean;
23+
};
24+
1925
export type AuthenticationOptsResponse = {
2026
options: PublicKeyCredentialCreationOptionsJSON;
27+
challengeId?: string;
2128
};
2229

2330
export type AddAuthenticatorRequest = {
2431
registrationCredential: RegistrationResponseJSON;
2532
conditionalCreate?: boolean;
33+
challengeId?: string;
34+
useCookies?: boolean;
2635
};
2736

2837
export type AddAuthenticatorResponse = {
@@ -36,7 +45,7 @@ export type AddAuthenticatorResponse = {
3645
export type VerifyRequest = {
3746
authenticationCredential: AuthenticationResponseJSON;
3847
deviceId?: string;
39-
cookies?: boolean;
48+
useCookies?: boolean;
4049
};
4150

4251
export type VerifyResponse = {
@@ -53,6 +62,11 @@ export type PasskeyAuthenticatorResponse = {
5362
verifiedAt: string;
5463
};
5564

65+
export type ChallengeRequest = {
66+
action?: string;
67+
useCookies?: boolean;
68+
};
69+
5670
export type ChallengeResponse = {
5771
challengeId: string;
5872
};

src/passkey.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {TokenCache} from "./token-cache";
1111
import {handleErrorResponse, handleWebAuthnError} from "./helpers";
1212
import {AuthsignalResponse} from "./types";
1313
import {Authenticator} from "./api/types/shared";
14+
1415
type PasskeyOptions = {
1516
baseUrl: string;
1617
tenantId: string;
@@ -24,6 +25,7 @@ type SignUpParams = {
2425
displayName?: string;
2526
authenticatorAttachment?: AuthenticatorAttachment | null;
2627
useAutoRegister?: boolean;
28+
useCookies?: boolean;
2729
};
2830

2931
type SignUpResponse = {
@@ -36,7 +38,7 @@ type SignInParams = {
3638
autofill?: boolean;
3739
action?: string;
3840
token?: string;
39-
cookies?: boolean;
41+
useCookies?: boolean;
4042
onVerificationStarted?: () => unknown;
4143
};
4244

@@ -69,6 +71,7 @@ export class Passkey {
6971
token,
7072
authenticatorAttachment = "platform",
7173
useAutoRegister = false,
74+
useCookies = false,
7275
}: SignUpParams): Promise<AuthsignalResponse<SignUpResponse>> {
7376
const userToken = token ?? this.cache.token;
7477

@@ -87,6 +90,7 @@ export class Passkey {
8790
displayName,
8891
token: userToken,
8992
authenticatorAttachment,
93+
useCookies,
9094
};
9195

9296
const optionsResponse = await this.api.registrationOptions(optionsInput);
@@ -102,6 +106,7 @@ export class Passkey {
102106
registrationCredential: registrationResponse,
103107
token: userToken,
104108
conditionalCreate: useAutoRegister,
109+
useCookies,
105110
});
106111

107112
if ("error" in addAuthenticatorResponse) {
@@ -152,17 +157,20 @@ export class Passkey {
152157
}
153158
}
154159

155-
const challengeResponse = params?.action ? await this.api.challenge(params.action) : null;
160+
const challengeResponse = params?.action
161+
? await this.api.challenge({action: params?.action, useCookies: params?.useCookies})
162+
: null;
156163

157164
if (challengeResponse && "error" in challengeResponse) {
158165
autofillRequestPending = false;
159166

160167
return handleErrorResponse(challengeResponse);
161168
}
162169

163-
const optionsResponse = params?.action
164-
? await this.api.authenticationOptions({token: params?.token})
165-
: await this.api.authenticationOptionsWeb({token: params?.token});
170+
const optionsResponse =
171+
params?.action || !params?.useCookies
172+
? await this.api.authenticationOptions({token: params?.token})
173+
: await this.api.authenticationOptionsWeb({token: params?.token});
166174

167175
if ("error" in optionsResponse) {
168176
autofillRequestPending = false;
@@ -184,6 +192,7 @@ export class Passkey {
184192
authenticationCredential: authenticationResponse,
185193
token: params?.token,
186194
deviceId: this.anonymousId,
195+
useCookies: params?.useCookies,
187196
});
188197

189198
if ("error" in verifyResponse) {

0 commit comments

Comments
 (0)