UNPKG

better-auth

Version:

The most comprehensive authentication framework for TypeScript.

1 lines • 6.03 kB
{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/plugins/email-otp/index.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"@better-auth/core\";\nimport { createAuthMiddleware } from \"@better-auth/core/api\";\nimport { generateRandomString } from \"../../crypto\";\nimport { getDate } from \"../../utils/date\";\nimport { getEndpointResponse } from \"../../utils/plugin-helper\";\nimport { storeOTP } from \"./otp-token\";\nimport {\n\tcheckVerificationOTP,\n\tcreateVerificationOTP,\n\tERROR_CODES,\n\tforgetPasswordEmailOTP,\n\tgetVerificationOTP,\n\tresetPasswordEmailOTP,\n\tsendVerificationOTP,\n\tsignInEmailOTP,\n\tverifyEmailOTP,\n} from \"./routes\";\nimport type { EmailOTPOptions } from \"./types\";\n\nexport type { EmailOTPOptions } from \"./types\";\n\nconst defaultOTPGenerator = (options: EmailOTPOptions) =>\n\tgenerateRandomString(options.otpLength ?? 6, \"0-9\");\n\nexport const emailOTP = (options: EmailOTPOptions) => {\n\tconst opts = {\n\t\texpiresIn: 5 * 60,\n\t\tgenerateOTP: () => defaultOTPGenerator(options),\n\t\tstoreOTP: \"plain\",\n\t\t...options,\n\t} satisfies EmailOTPOptions;\n\n\tconst sendVerificationOTPAction = sendVerificationOTP(opts);\n\n\treturn {\n\t\tid: \"email-otp\",\n\t\tinit(ctx) {\n\t\t\tif (!opts.overrideDefaultEmailVerification) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toptions: {\n\t\t\t\t\temailVerification: {\n\t\t\t\t\t\tasync sendVerificationEmail(data, request) {\n\t\t\t\t\t\t\tawait ctx.runInBackgroundOrAwait(\n\t\t\t\t\t\t\t\tsendVerificationOTPAction({\n\t\t\t\t\t\t\t\t\t//@ts-expect-error - we need to pass the context\n\t\t\t\t\t\t\t\t\tcontext: ctx,\n\t\t\t\t\t\t\t\t\trequest: request,\n\t\t\t\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\t\t\t\temail: data.user.email,\n\t\t\t\t\t\t\t\t\t\ttype: \"email-verification\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t},\n\t\tendpoints: {\n\t\t\tsendVerificationOTP: sendVerificationOTPAction,\n\t\t\tcreateVerificationOTP: createVerificationOTP(opts),\n\t\t\tgetVerificationOTP: getVerificationOTP(opts),\n\t\t\tcheckVerificationOTP: checkVerificationOTP(opts),\n\t\t\tverifyEmailOTP: verifyEmailOTP(opts),\n\t\t\tsignInEmailOTP: signInEmailOTP(opts),\n\t\t\tforgetPasswordEmailOTP: forgetPasswordEmailOTP(opts),\n\t\t\tresetPasswordEmailOTP: resetPasswordEmailOTP(opts),\n\t\t},\n\t\thooks: {\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher(context) {\n\t\t\t\t\t\treturn !!(\n\t\t\t\t\t\t\tcontext.path?.startsWith(\"/sign-up\") &&\n\t\t\t\t\t\t\topts.sendVerificationOnSignUp &&\n\t\t\t\t\t\t\t!opts.overrideDefaultEmailVerification\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst response = await getEndpointResponse<{\n\t\t\t\t\t\t\tuser: { email: string };\n\t\t\t\t\t\t}>(ctx);\n\t\t\t\t\t\tconst email = response?.user.email;\n\t\t\t\t\t\tif (email) {\n\t\t\t\t\t\t\tconst otp =\n\t\t\t\t\t\t\t\topts.generateOTP({ email, type: ctx.body.type }, ctx) ||\n\t\t\t\t\t\t\t\tdefaultOTPGenerator(opts);\n\t\t\t\t\t\t\tlet storedOTP = await storeOTP(ctx, opts, otp);\n\t\t\t\t\t\t\tawait ctx.context.internalAdapter.createVerificationValue({\n\t\t\t\t\t\t\t\tvalue: `${storedOTP}:0`,\n\t\t\t\t\t\t\t\tidentifier: `email-verification-otp-${email}`,\n\t\t\t\t\t\t\t\texpiresAt: getDate(opts.expiresIn, \"sec\"),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tawait ctx.context.runInBackgroundOrAwait(\n\t\t\t\t\t\t\t\toptions.sendVerificationOTP(\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\temail,\n\t\t\t\t\t\t\t\t\t\totp,\n\t\t\t\t\t\t\t\t\t\ttype: \"email-verification\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tctx,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t$ERROR_CODES: ERROR_CODES,\n\t\trateLimit: [\n\t\t\t{\n\t\t\t\tpathMatcher(path) {\n\t\t\t\t\treturn path === \"/email-otp/send-verification-otp\";\n\t\t\t\t},\n\t\t\t\twindow: 60,\n\t\t\t\tmax: 3,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpathMatcher(path) {\n\t\t\t\t\treturn path === \"/email-otp/check-verification-otp\";\n\t\t\t\t},\n\t\t\t\twindow: 60,\n\t\t\t\tmax: 3,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpathMatcher(path) {\n\t\t\t\t\treturn path === \"/email-otp/verify-email\";\n\t\t\t\t},\n\t\t\t\twindow: 60,\n\t\t\t\tmax: 3,\n\t\t\t},\n\t\t\t{\n\t\t\t\tpathMatcher(path) {\n\t\t\t\t\treturn path === \"/sign-in/email-otp\";\n\t\t\t\t},\n\t\t\t\twindow: 60,\n\t\t\t\tmax: 3,\n\t\t\t},\n\t\t],\n\t\toptions,\n\t} satisfies BetterAuthPlugin;\n};\n"],"mappings":";;;;;;;;;AAqBA,MAAM,uBAAuB,YAC5B,qBAAqB,QAAQ,aAAa,GAAG,MAAM;AAEpD,MAAa,YAAY,YAA6B;CACrD,MAAM,OAAO;EACZ,WAAW;EACX,mBAAmB,oBAAoB,QAAQ;EAC/C,UAAU;EACV,GAAG;EACH;CAED,MAAM,4BAA4B,oBAAoB,KAAK;AAE3D,QAAO;EACN,IAAI;EACJ,KAAK,KAAK;AACT,OAAI,CAAC,KAAK,iCACT;AAED,UAAO,EACN,SAAS,EACR,mBAAmB,EAClB,MAAM,sBAAsB,MAAM,SAAS;AAC1C,UAAM,IAAI,uBACT,0BAA0B;KAEzB,SAAS;KACA;KACT,MAAM;MACL,OAAO,KAAK,KAAK;MACjB,MAAM;MACN;KACD;KACA,CAAC,CACF;MAEF,EACD,EACD;;EAEF,WAAW;GACV,qBAAqB;GACrB,uBAAuB,sBAAsB,KAAK;GAClD,oBAAoB,mBAAmB,KAAK;GAC5C,sBAAsB,qBAAqB,KAAK;GAChD,gBAAgB,eAAe,KAAK;GACpC,gBAAgB,eAAe,KAAK;GACpC,wBAAwB,uBAAuB,KAAK;GACpD,uBAAuB,sBAAsB,KAAK;GAClD;EACD,OAAO,EACN,OAAO,CACN;GACC,QAAQ,SAAS;AAChB,WAAO,CAAC,EACP,QAAQ,MAAM,WAAW,WAAW,IACpC,KAAK,4BACL,CAAC,KAAK;;GAGR,SAAS,qBAAqB,OAAO,QAAQ;IAI5C,MAAM,SAHW,MAAM,oBAEpB,IAAI,GACiB,KAAK;AAC7B,QAAI,OAAO;KACV,MAAM,MACL,KAAK,YAAY;MAAE;MAAO,MAAM,IAAI,KAAK;MAAM,EAAE,IAAI,IACrD,oBAAoB,KAAK;KAC1B,IAAI,YAAY,MAAM,SAAS,KAAK,MAAM,IAAI;AAC9C,WAAM,IAAI,QAAQ,gBAAgB,wBAAwB;MACzD,OAAO,GAAG,UAAU;MACpB,YAAY,0BAA0B;MACtC,WAAW,QAAQ,KAAK,WAAW,MAAM;MACzC,CAAC;AACF,WAAM,IAAI,QAAQ,uBACjB,QAAQ,oBACP;MACC;MACA;MACA,MAAM;MACN,EACD,IACA,CACD;;KAED;GACF,CACD,EACD;EACD,cAAc;EACd,WAAW;GACV;IACC,YAAY,MAAM;AACjB,YAAO,SAAS;;IAEjB,QAAQ;IACR,KAAK;IACL;GACD;IACC,YAAY,MAAM;AACjB,YAAO,SAAS;;IAEjB,QAAQ;IACR,KAAK;IACL;GACD;IACC,YAAY,MAAM;AACjB,YAAO,SAAS;;IAEjB,QAAQ;IACR,KAAK;IACL;GACD;IACC,YAAY,MAAM;AACjB,YAAO,SAAS;;IAEjB,QAAQ;IACR,KAAK;IACL;GACD;EACD;EACA"}