mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 22:21:10 +02:00
fix(auth): use correct Better Auth API method for password reset
- Fix `requestPasswordReset` method name (was incorrectly `forgetPassword`) - Add proper TypeScript types for password reset, session, and JWT methods - Consolidate API accessor from `orgApi` to `api` for all Better Auth calls - Remove unnecessary `as any` casts by extending BetterAuthAPI interface - Clean up unused imports 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
78cd59a77a
commit
eeab9b7fea
3 changed files with 40 additions and 28 deletions
|
|
@ -91,8 +91,8 @@ export function createBetterAuth(databaseUrl: string) {
|
|||
* Password Reset Configuration
|
||||
*
|
||||
* Better Auth provides password reset via:
|
||||
* - auth.api.forgetPassword({ email }) - Sends reset email
|
||||
* - auth.api.resetPassword({ newPassword, token }) - Resets password
|
||||
* - auth.api.requestPasswordReset({ body: { email } }) - Sends reset email
|
||||
* - auth.api.resetPassword({ body: { newPassword, token } }) - Resets password
|
||||
*
|
||||
* @see https://www.better-auth.com/docs/authentication/email-password#password-reset
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -56,11 +56,8 @@ import type {
|
|||
OrganizationMember,
|
||||
Organization,
|
||||
BetterAuthAPI,
|
||||
SignUpResponse,
|
||||
SignInResponse,
|
||||
CreateOrganizationResponse,
|
||||
BetterAuthUser,
|
||||
BetterAuthSession,
|
||||
} from '../types/better-auth.types';
|
||||
import * as jwt from 'jsonwebtoken';
|
||||
import { jwtVerify, createRemoteJWKSet } from 'jose';
|
||||
|
|
@ -89,11 +86,13 @@ export class BetterAuthService {
|
|||
private databaseUrl: string;
|
||||
|
||||
/**
|
||||
* Typed accessor for organization plugin API methods
|
||||
* Better Auth's organization plugin adds methods dynamically, so we provide
|
||||
* Typed accessor for Better Auth API methods
|
||||
* Better Auth's plugins add methods dynamically, so we provide
|
||||
* a typed accessor to avoid casting throughout the service.
|
||||
*
|
||||
* @see https://www.better-auth.com/docs/concepts/typescript
|
||||
*/
|
||||
private get orgApi(): BetterAuthAPI {
|
||||
private get api(): BetterAuthAPI {
|
||||
return this.auth.api as unknown as BetterAuthAPI;
|
||||
}
|
||||
|
||||
|
|
@ -245,7 +244,7 @@ export class BetterAuthService {
|
|||
try {
|
||||
// Better Auth organization plugin uses auth.api.inviteMember
|
||||
// See: https://www.better-auth.com/docs/plugins/organization
|
||||
const result = await this.orgApi.inviteMember({
|
||||
const result = await this.api.inviteMember({
|
||||
body: {
|
||||
email: dto.employeeEmail,
|
||||
role: dto.role,
|
||||
|
|
@ -286,7 +285,7 @@ export class BetterAuthService {
|
|||
try {
|
||||
// Better Auth organization plugin uses auth.api.acceptInvitation
|
||||
// See: https://www.better-auth.com/docs/plugins/organization
|
||||
const result = await this.orgApi.acceptInvitation({
|
||||
const result = await this.api.acceptInvitation({
|
||||
body: { invitationId: dto.invitationId },
|
||||
headers: {
|
||||
authorization: `Bearer ${dto.userToken}`,
|
||||
|
|
@ -324,7 +323,7 @@ export class BetterAuthService {
|
|||
try {
|
||||
// Better Auth uses getFullOrganization to get org with members
|
||||
// See: https://www.better-auth.com/docs/plugins/organization
|
||||
const result = await this.orgApi.getFullOrganization({
|
||||
const result = await this.api.getFullOrganization({
|
||||
query: { organizationId },
|
||||
});
|
||||
|
||||
|
|
@ -353,7 +352,7 @@ export class BetterAuthService {
|
|||
// Better Auth organization plugin uses auth.api.removeMember
|
||||
// Accepts memberIdOrEmail parameter
|
||||
// See: https://www.better-auth.com/docs/plugins/organization
|
||||
await this.orgApi.removeMember({
|
||||
await this.api.removeMember({
|
||||
body: {
|
||||
memberIdOrEmail: dto.memberId,
|
||||
organizationId: dto.organizationId,
|
||||
|
|
@ -388,7 +387,7 @@ export class BetterAuthService {
|
|||
try {
|
||||
// Better Auth organization plugin uses auth.api.setActiveOrganization
|
||||
// See: https://www.better-auth.com/docs/plugins/organization
|
||||
const result = await this.orgApi.setActiveOrganization({
|
||||
const result = await this.api.setActiveOrganization({
|
||||
body: { organizationId: dto.organizationId },
|
||||
headers: {
|
||||
authorization: `Bearer ${dto.userToken}`,
|
||||
|
|
@ -441,10 +440,8 @@ export class BetterAuthService {
|
|||
// Generate JWT access token using Better Auth's JWT plugin
|
||||
let accessToken = '';
|
||||
try {
|
||||
const api = this.auth.api as any;
|
||||
|
||||
// Use Better Auth's signJWT with the jwks table
|
||||
const jwtResult = await api.signJWT({
|
||||
const jwtResult = await this.api.signJWT({
|
||||
body: {
|
||||
payload: {
|
||||
sub: user.id,
|
||||
|
|
@ -537,7 +534,7 @@ export class BetterAuthService {
|
|||
async signOut(token: string): Promise<SignOutResult> {
|
||||
try {
|
||||
// Better Auth uses auth.api.signOut
|
||||
await (this.auth.api as any).signOut({
|
||||
await this.api.signOut({
|
||||
headers: {
|
||||
authorization: `Bearer ${token}`,
|
||||
},
|
||||
|
|
@ -564,7 +561,7 @@ export class BetterAuthService {
|
|||
async getSession(token: string): Promise<GetSessionResult> {
|
||||
try {
|
||||
// Better Auth uses auth.api.getSession
|
||||
const result = await (this.auth.api as any).getSession({
|
||||
const result = await this.api.getSession({
|
||||
headers: {
|
||||
authorization: `Bearer ${token}`,
|
||||
},
|
||||
|
|
@ -602,7 +599,7 @@ export class BetterAuthService {
|
|||
*/
|
||||
async listOrganizations(token: string): Promise<ListOrganizationsResult> {
|
||||
try {
|
||||
const result = await this.orgApi.listOrganizations({
|
||||
const result = await this.api.listOrganizations({
|
||||
headers: {
|
||||
authorization: `Bearer ${token}`,
|
||||
},
|
||||
|
|
@ -633,7 +630,7 @@ export class BetterAuthService {
|
|||
token?: string
|
||||
): Promise<Organization & { members?: OrganizationMember[] }> {
|
||||
try {
|
||||
const result = await this.orgApi.getFullOrganization({
|
||||
const result = await this.api.getFullOrganization({
|
||||
query: { organizationId },
|
||||
...(token && {
|
||||
headers: {
|
||||
|
|
@ -864,9 +861,9 @@ export class BetterAuthService {
|
|||
redirectTo?: string
|
||||
): Promise<{ success: boolean; message: string }> {
|
||||
try {
|
||||
// Better Auth's forgetPassword method
|
||||
// Better Auth's requestPasswordReset method
|
||||
// See: https://www.better-auth.com/docs/authentication/email-password#password-reset
|
||||
await (this.auth.api as any).forgetPassword({
|
||||
await this.api.requestPasswordReset({
|
||||
body: {
|
||||
email,
|
||||
redirectTo,
|
||||
|
|
@ -906,7 +903,7 @@ export class BetterAuthService {
|
|||
try {
|
||||
// Better Auth's resetPassword method
|
||||
// See: https://www.better-auth.com/docs/authentication/email-password#password-reset
|
||||
await (this.auth.api as any).resetPassword({
|
||||
await this.api.resetPassword({
|
||||
body: {
|
||||
token,
|
||||
newPassword,
|
||||
|
|
@ -941,12 +938,9 @@ export class BetterAuthService {
|
|||
*/
|
||||
async getJwks(): Promise<{ keys: unknown[] }> {
|
||||
try {
|
||||
// Better Auth exposes JWKS via auth.api
|
||||
const api = this.auth.api as any;
|
||||
|
||||
// Try to get JWKS from Better Auth
|
||||
if (api.getJwks) {
|
||||
const result = await api.getJwks();
|
||||
const result = await this.api.getJwks();
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -268,11 +268,29 @@ export interface AuthenticatedRequest<TBody = unknown, TQuery = unknown> {
|
|||
*
|
||||
* This interface describes the methods available on auth.api
|
||||
* when using the organization plugin.
|
||||
*
|
||||
* @see https://www.better-auth.com/docs/concepts/typescript
|
||||
*/
|
||||
export interface BetterAuthAPI {
|
||||
// Core auth methods
|
||||
signUpEmail(params: { body: SignUpEmailBody }): Promise<SignUpResponse>;
|
||||
signInEmail(params: { body: { email: string; password: string } }): Promise<SignInResponse>;
|
||||
signOut(params: AuthenticatedRequest): Promise<{ success: boolean }>;
|
||||
getSession(
|
||||
params: AuthenticatedRequest
|
||||
): Promise<{ user: BetterAuthUser; session: BetterAuthSession }>;
|
||||
|
||||
// Password reset methods
|
||||
requestPasswordReset(params: {
|
||||
body: { email: string; redirectTo?: string };
|
||||
}): Promise<{ status: boolean }>;
|
||||
resetPassword(params: {
|
||||
body: { newPassword: string; token: string };
|
||||
}): Promise<{ status: boolean }>;
|
||||
|
||||
// JWT methods
|
||||
signJWT(params: { body: { payload: Record<string, unknown> } }): Promise<{ token: string }>;
|
||||
getJwks(): Promise<{ keys: unknown[] }>;
|
||||
|
||||
// Organization methods
|
||||
createOrganization(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue