Authentication flows
First-party passwordless login
Use Salesforce OAuth 2.0 for First-Party Applications passwordless email or SMS OTP login.
The first-party passwordless flow sends an OTP to the user's verified email address or phone number, then resumes the authorization challenge with the OTP to obtain an authorization code.
Initialize passwordless login
import { SalesforceAuth } from "@kysoql/auth";
export function beginPasswordless(
username: string,
clientAssertion: string,
codeChallenge: string,
) {
const auth = new SalesforceAuth({
loginUrl: "https://customers.example.my.site.com/customers",
clientId: "external-client-app-id",
});
return auth.firstPartyAuthorizationChallenge({
parameters: {
username,
login_type: "email",
client_assertion: clientAssertion,
client_id: "external-client-app-id",
code_challenge: codeChallenge,
scope: "api refresh_token",
},
});
}A successful initialization is still a challenge response: Salesforce returns an
auth_session and a login state indicating that the OTP was sent.
Submit the OTP
import { SalesforceAuth } from "@kysoql/auth";
export function submitPasswordlessOtp(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,
},
});
}When Salesforce returns kind: "authorized", exchange the authorization code
through auth.exchangeAuthorizationCode() using the
matching PKCE verifier.
For identifier-based discovery instead of a Salesforce username, follow
Salesforce's login_hint/customdata requirements for this flow.