First-party registration
Use Salesforce OAuth 2.0 for First-Party Applications headless registration and OTP verification.
The first-party registration flow lets a private Experience Cloud application collect registration data, initialize Salesforce registration headlessly, verify the user with an OTP, and receive an authorization code.
Initialize registration
import { SalesforceAuth } from "@kysoql/auth";
export function beginRegistration(
clientAssertion: string,
codeChallenge: string,
) {
const auth = new SalesforceAuth({
loginUrl: "https://customers.example.my.site.com/customers",
clientId: "external-client-app-id",
});
return auth.firstPartyAuthorizationChallenge({
bodyFormat: "json",
parameters: {
userdata: {
username: "user@example.com",
lastName: "Example",
email: "user@example.com",
},
password: "user-chosen-password",
login_type: "email",
client_assertion: clientAssertion,
code_challenge: codeChallenge,
},
});
}Use accessToken when the Experience Cloud registration policy requires an
authenticated integration user. Kysoql adds it as an Authorization: Bearer
header. Use uvidHintToken when registration carries guest-session context.
Salesforce strongly recommends PKCE for this flow. Keep the matching
code_verifier and use it when exchanging the returned authorization code.
Salesforce can return an auth_session while it waits for OTP verification.
Submit the OTP
import { SalesforceAuth } from "@kysoql/auth";
export function submitRegistrationOtp(authSession: string, otp: string) {
const auth = new SalesforceAuth({
loginUrl: "https://customers.example.my.site.com/customers",
clientId: "external-client-app-id",
});
return auth.firstPartyAuthorizationChallenge({
parameters: {
auth_session: authSession,
login_otp: otp,
},
});
}After Salesforce returns kind: "authorized", exchange the authorization code
through auth.exchangeAuthorizationCode().