SocialAuthService
Package: @nauth-toolkit/core
Type: Service
Service for managing social authentication accounts and their relationships. Provides account linking/unlinking, password management for social-only users, and account queries.
- NestJS
- Express
- Fastify
import { SocialAuthService } from '@nauth-toolkit/nestjs';
import { SocialAuthService } from '@nauth-toolkit/core';
// Access via nauth.socialAuthService after NAuth.create()
import { SocialAuthService } from '@nauth-toolkit/core';
// Access via nauth.socialAuthService after NAuth.create()
Overview
Service for managing social authentication accounts and their relationships. This service provides account linking/unlinking, password management for social-only users, and querying linked accounts.
For OAuth authentication (login/signup), use SocialRedirectHandler or the frontend SDK's loginWithSocial() method. See the Social Login Guide for details.
Only available when social auth provider modules are imported (e.g., GoogleSocialAuthModule, AppleSocialAuthModule).
Auto-injected by framework. No manual instantiation required.
Methods
canSetPassword()
Check if user can set a password (social-only users can set passwords).
async canSetPassword(dto: CanSetPasswordDTO): Promise<CanSetPasswordResponseDTO>
Parameters
dto-CanSetPasswordDTO
Returns
Example
- NestJS
- Express
- Fastify
import { CanSetPasswordDTO } from '@nauth-toolkit/nestjs';
const dto: CanSetPasswordDTO = { userId: user.sub };
const result = await this.socialAuthService.canSetPassword(dto);
if (result.canSetPassword) {
// Show password setup form
}
import { CanSetPasswordDTO } from '@nauth-toolkit/core';
const dto: CanSetPasswordDTO = { userId: user.sub };
const result = await nauth.socialAuthService.canSetPassword(dto);
if (result.canSetPassword) {
// Show password setup form
}
import { CanSetPasswordDTO } from '@nauth-toolkit/core';
const dto: CanSetPasswordDTO = { userId: user.sub };
const result = await nauth.socialAuthService.canSetPassword(dto);
if (result.canSetPassword) {
// Show password setup form
}
getLinkedAccounts()
Get linked social accounts for a user.
async getLinkedAccounts(dto: GetLinkedAccountsDTO): Promise<GetLinkedAccountsResponseDTO>
Parameters
dto-GetLinkedAccountsDTO
Returns
Errors
| Code | When | Details |
|---|---|---|
NOT_FOUND | User not found | { userId?: string } |
Example
- NestJS
- Express
- Fastify
import { GetLinkedAccountsDTO } from '@nauth-toolkit/nestjs';
@Get('social/linked')
async getLinked(@CurrentUser() user: IUser) {
const dto: GetLinkedAccountsDTO = { userId: user.sub };
const accounts = await this.socialAuthService.getLinkedAccounts(dto);
return accounts.accounts;
}
import { GetLinkedAccountsDTO } from '@nauth-toolkit/core';
app.get('/auth/social/linked', nauth.helpers.requireAuth(), async (req, res) => {
const user = nauth.helpers.getCurrentUser(req);
const dto: GetLinkedAccountsDTO = { userId: user!.sub };
const accounts = await nauth.socialAuthService.getLinkedAccounts(dto);
res.json(accounts.accounts);
});
import { GetLinkedAccountsDTO } from '@nauth-toolkit/core';
fastify.get(
'/auth/social/linked',
{ preHandler: nauth.helpers.requireAuth() },
nauth.adapter.wrapRouteHandler(async (req, reply) => {
const user = nauth.helpers.getCurrentUser();
const dto: GetLinkedAccountsDTO = { userId: user!.sub };
const accounts = await nauth.socialAuthService.getLinkedAccounts(dto);
return accounts.accounts;
}),
);
linkSocialAccount()
Link social account to existing authenticated user.
async linkSocialAccount(dto: LinkSocialAccountDTO): Promise<LinkSocialAccountResponseDTO>
Parameters
dto-LinkSocialAccountDTO
Returns
Errors
| Code | When | Details |
|---|---|---|
SOCIAL_ACCOUNT_LINKED | Account already linked | {} |
NOT_FOUND | User not found | { userId?: string } |
SOCIAL_CONFIG_MISSING | Provider not configured | {} |
SOCIAL_TOKEN_INVALID | OAuth callback failed | {} |
Example
- NestJS
- Express
- Fastify
import { LinkSocialAccountDTO } from '@nauth-toolkit/nestjs';
@Post('social/link')
async link(@CurrentUser() user: IUser, @Body() body: { provider: string; code: string; state: string }) {
const dto: LinkSocialAccountDTO = {
userId: user.sub,
...body,
};
return await this.socialAuthService.linkSocialAccount(dto);
}
import { LinkSocialAccountDTO } from '@nauth-toolkit/core';
app.post('/auth/social/link', nauth.helpers.requireAuth(), async (req, res) => {
const user = nauth.helpers.getCurrentUser(req);
const dto: LinkSocialAccountDTO = {
userId: user!.sub,
...req.body,
};
const result = await nauth.socialAuthService.linkSocialAccount(dto);
res.json(result);
});
import { LinkSocialAccountDTO } from '@nauth-toolkit/core';
fastify.post(
'/auth/social/link',
{ preHandler: nauth.helpers.requireAuth() },
nauth.adapter.wrapRouteHandler(async (req, reply) => {
const user = nauth.helpers.getCurrentUser();
const dto: LinkSocialAccountDTO = {
userId: user!.sub,
...req.body,
};
const result = await nauth.socialAuthService.linkSocialAccount(dto);
return result;
}),
);
listAvailableProviders()
List available social auth providers.
listAvailableProviders(): string[]
Parameters
None
Returns
string[]- Array of provider names (e.g., ['google', 'apple', 'facebook'])
Example
- NestJS
- Express
- Fastify
const providers = this.socialAuthService.listAvailableProviders();
// ['google', 'apple']
const providers = nauth.socialAuthService.listAvailableProviders();
// ['google', 'apple']
const providers = nauth.socialAuthService.listAvailableProviders();
// ['google', 'apple']
setPasswordForSocialUser()
Set password for social-only user.
async setPasswordForSocialUser(dto: SetPasswordForSocialUserDTO): Promise<SetPasswordForSocialUserResponseDTO>
Parameters
Returns
Errors
| Code | When | Details |
|---|---|---|
NOT_FOUND | User not found | { userId?: string } |
VALIDATION_FAILED | User already has password | { field: 'password' } |
WEAK_PASSWORD | Password policy violation | { errors: string[] } |
Example
- NestJS
- Express
- Fastify
import { SetPasswordForSocialUserDTO } from '@nauth-toolkit/nestjs';
const dto: SetPasswordForSocialUserDTO = {
userId: user.sub,
password: 'newpassword',
};
await this.socialAuthService.setPasswordForSocialUser(dto);
import { SetPasswordForSocialUserDTO } from '@nauth-toolkit/core';
const dto: SetPasswordForSocialUserDTO = {
userId: user.sub,
password: 'newpassword',
};
await nauth.socialAuthService.setPasswordForSocialUser(dto);
import { SetPasswordForSocialUserDTO } from '@nauth-toolkit/core';
const dto: SetPasswordForSocialUserDTO = {
userId: user.sub,
password: 'newpassword',
};
await nauth.socialAuthService.setPasswordForSocialUser(dto);
unlinkSocialAccount()
Unlink social account from user.
async unlinkSocialAccount(dto: UnlinkSocialAccountDTO): Promise<UnlinkSocialAccountResponseDTO>
Parameters
dto-UnlinkSocialAccountDTO
Returns
Errors
| Code | When | Details |
|---|---|---|
NOT_FOUND | User not found | { userId?: string } |
SOCIAL_ACCOUNT_NOT_FOUND | Account not linked | {} |
Example
- NestJS
- Express
- Fastify
import { UnlinkSocialAccountDTO } from '@nauth-toolkit/nestjs';
@Post('social/unlink')
async unlink(@CurrentUser() user: IUser, @Body() body: { provider: string }) {
const dto: UnlinkSocialAccountDTO = {
userId: user.sub,
provider: body.provider,
};
await this.socialAuthService.unlinkSocialAccount(dto);
return { success: true };
}
import { UnlinkSocialAccountDTO } from '@nauth-toolkit/core';
app.post('/auth/social/unlink', nauth.helpers.requireAuth(), async (req, res) => {
const user = nauth.helpers.getCurrentUser(req);
const dto: UnlinkSocialAccountDTO = {
userId: user!.sub,
provider: req.body.provider,
};
await nauth.socialAuthService.unlinkSocialAccount(dto);
res.json({ success: true });
});
import { UnlinkSocialAccountDTO } from '@nauth-toolkit/core';
fastify.post(
'/auth/social/unlink',
{ preHandler: nauth.helpers.requireAuth() },
nauth.adapter.wrapRouteHandler(async (req, reply) => {
const user = nauth.helpers.getCurrentUser();
const dto: UnlinkSocialAccountDTO = {
userId: user!.sub,
provider: req.body.provider,
};
await nauth.socialAuthService.unlinkSocialAccount(dto);
return { success: true };
}),
);
Error Handling
All methods throw NAuthException on failure. Handle errors appropriately for your framework.
- NestJS
- Express
- Fastify
try {
await this.socialAuthService.linkSocialAccount(dto);
} catch (error) {
if (error instanceof NAuthException) {
console.log(error.code);
}
}
try {
await nauth.socialAuthService.linkSocialAccount(dto);
} catch (error) {
if (error instanceof NAuthException) {
res.status(error.statusCode).json(error.toJSON());
}
}
try {
await nauth.socialAuthService.linkSocialAccount(dto);
} catch (error) {
if (error instanceof NAuthException) {
reply.status(error.statusCode).send(error.toJSON());
}
}
See Error Handling Guide.
Redirect-first OAuth (SocialRedirectHandler)
For backend-first OAuth flows (redirect to provider, then callback), use SocialRedirectHandler (injected alongside this service). The handler is framework-neutral: it reads delivery and deviceToken from ContextStorage and applies cookies via HTTP_RESPONSE in cookies mode. Consumer controllers pass only provider and DTOs.
start(provider, dto)- ReturnsPromise<StartSocialRedirectResponseDTO>. Use with NestJS@Redirect().callback(provider, dto)- ReturnsPromise<SocialRedirectCallbackResponseDTO>. Cookies are applied to the response from ContextStorage when delivery is cookies.exchange(exchangeToken)- ReturnsPromise<AuthResponseDTO>for JSON/hybrid or challenge flows.
See the Social Login Guide for full implementation and DTOs (StartSocialRedirectQueryDTO, SocialCallbackQueryDTO, SocialCallbackFormDTO, StartSocialRedirectResponseDTO, SocialRedirectCallbackResponseDTO).
Related APIs
- AuthService - Core authentication service
- NAuthException - Error handling
- Social Login Guide - Implementation guide