@guettonenrique/passwordless-auth 0.0.0-stage → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +387 -2
- package/dist/functions/index.cjs +391 -0
- package/dist/functions/index.cjs.map +1 -0
- package/dist/functions/index.d.cts +70 -0
- package/dist/functions/index.d.ts +70 -0
- package/dist/functions/index.js +348 -0
- package/dist/functions/index.js.map +1 -0
- package/dist/react-native/index.cjs +617 -0
- package/dist/react-native/index.cjs.map +1 -0
- package/dist/react-native/index.d.cts +64 -0
- package/dist/react-native/index.d.ts +64 -0
- package/dist/react-native/index.js +606 -0
- package/dist/react-native/index.js.map +1 -0
- package/dist/shared/index.cjs +151 -0
- package/dist/shared/index.cjs.map +1 -0
- package/dist/shared/index.d.cts +50 -0
- package/dist/shared/index.d.ts +50 -0
- package/dist/shared/index.js +111 -0
- package/dist/shared/index.js.map +1 -0
- package/dist/types-BUi8ZPam.d.cts +110 -0
- package/dist/types-BUi8ZPam.d.ts +110 -0
- package/package.json +91 -4
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
interface RequestOtpPayload {
|
|
2
|
+
email: string;
|
|
3
|
+
}
|
|
4
|
+
interface VerifyOtpPayload {
|
|
5
|
+
email: string;
|
|
6
|
+
code: string;
|
|
7
|
+
}
|
|
8
|
+
interface RequestOtpResponse {
|
|
9
|
+
status: 'success';
|
|
10
|
+
message: string;
|
|
11
|
+
}
|
|
12
|
+
interface VerifyOtpResponse {
|
|
13
|
+
status: 'success';
|
|
14
|
+
/** Firebase custom auth token — exchange with signInWithCustomToken. */
|
|
15
|
+
customToken: string;
|
|
16
|
+
}
|
|
17
|
+
/** A fully composed OTP email, ready to dispatch. */
|
|
18
|
+
interface OtpEmail {
|
|
19
|
+
to: string;
|
|
20
|
+
subject: string;
|
|
21
|
+
text: string;
|
|
22
|
+
html: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Delivers the OTP email. The default implementation sends via SendGrid;
|
|
26
|
+
* projects can replace it entirely (custom provider, or a console-logging
|
|
27
|
+
* sender during development).
|
|
28
|
+
*/
|
|
29
|
+
type OtpEmailSender = (email: OtpEmail) => Promise<void>;
|
|
30
|
+
/** Inputs for {@link buildOtpEmail}. */
|
|
31
|
+
interface OtpEmailInput {
|
|
32
|
+
to: string;
|
|
33
|
+
appName: string;
|
|
34
|
+
/** The plaintext 6-digit code — only ever passed to the sender, never persisted. */
|
|
35
|
+
code: string;
|
|
36
|
+
/** Code lifetime in minutes, for the email copy. */
|
|
37
|
+
expiresMinutes: number;
|
|
38
|
+
}
|
|
39
|
+
interface SendgridSenderOptions {
|
|
40
|
+
/**
|
|
41
|
+
* The API key, resolved per call. Accepts a plain string, a getter
|
|
42
|
+
* function (`defineSecret('X').value`), or a Firebase params Secret
|
|
43
|
+
* object (`defineSecret('X')`) directly.
|
|
44
|
+
*/
|
|
45
|
+
apiKey: string | (() => string) | {
|
|
46
|
+
value: () => string;
|
|
47
|
+
};
|
|
48
|
+
fromEmail: string;
|
|
49
|
+
fromName: string;
|
|
50
|
+
}
|
|
51
|
+
/** Base options shared by the request/verify factories. */
|
|
52
|
+
interface BaseOtpOptions {
|
|
53
|
+
/** Firestore collection holding pending OTPs. Default: `auth_otps`. */
|
|
54
|
+
collection?: string;
|
|
55
|
+
/** Resend cooldown in ms. Default: 60_000. */
|
|
56
|
+
cooldownMs?: number;
|
|
57
|
+
/** Code lifetime in ms. Default: 600_000 (10 minutes). */
|
|
58
|
+
expiryMs?: number;
|
|
59
|
+
/** Failed verifications before the code is invalidated. Default: 5. */
|
|
60
|
+
maxAttempts?: number;
|
|
61
|
+
/** Enforce App Check on the callable. Default: false (flip true in production). */
|
|
62
|
+
enforceAppCheck?: boolean;
|
|
63
|
+
}
|
|
64
|
+
interface RequestOtpOptions extends BaseOtpOptions {
|
|
65
|
+
/** Brand name used in the email subject and body. Required. */
|
|
66
|
+
appName: string;
|
|
67
|
+
/** Replace the default SendGrid delivery entirely. */
|
|
68
|
+
sendEmail?: OtpEmailSender;
|
|
69
|
+
/** SendGrid sender config; required unless `sendEmail` is provided. */
|
|
70
|
+
sendgrid?: SendgridSenderOptions;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolves (and, if needed, creates) the auth user for an email, returning
|
|
74
|
+
* the uid the custom token will be minted for. This is the one required
|
|
75
|
+
* project-specific hook — it owns the app's user schema.
|
|
76
|
+
*/
|
|
77
|
+
type OtpProvisioner = (email: string) => Promise<string>;
|
|
78
|
+
interface VerifyOtpOptions extends BaseOtpOptions {
|
|
79
|
+
/** Required. Creates or resolves the user and returns their uid. */
|
|
80
|
+
provision: OtpProvisioner;
|
|
81
|
+
}
|
|
82
|
+
interface CleanupOtpOptions {
|
|
83
|
+
/** Cloud Scheduler cron. Default: `every 15 minutes`. */
|
|
84
|
+
schedule?: string;
|
|
85
|
+
/** Collection to clean. Default: `auth_otps`. */
|
|
86
|
+
collection?: string;
|
|
87
|
+
/** Writes per batch. Default: 400 (Firestore limit is 500). */
|
|
88
|
+
batchSize?: number;
|
|
89
|
+
}
|
|
90
|
+
interface OtpDocumentData {
|
|
91
|
+
/** SHA-256 hex of `email:code`. The plaintext code is never stored. */
|
|
92
|
+
hash: string;
|
|
93
|
+
/** Failed guess counter. */
|
|
94
|
+
attempts: number;
|
|
95
|
+
/** Expiry as epoch milliseconds. */
|
|
96
|
+
expiresAt: number;
|
|
97
|
+
/** Last dispatch as epoch milliseconds (drives the resend cooldown). */
|
|
98
|
+
lastSentAt: number;
|
|
99
|
+
createdAt?: unknown;
|
|
100
|
+
}
|
|
101
|
+
declare const OTP_ERROR_CODES: {
|
|
102
|
+
readonly InvalidArgument: "invalid-argument";
|
|
103
|
+
readonly NotFound: "not-found";
|
|
104
|
+
readonly DeadlineExceeded: "deadline-exceeded";
|
|
105
|
+
readonly ResourceExhausted: "resource-exhausted";
|
|
106
|
+
readonly Internal: "internal";
|
|
107
|
+
};
|
|
108
|
+
type OtpErrorCode = (typeof OTP_ERROR_CODES)[keyof typeof OTP_ERROR_CODES];
|
|
109
|
+
|
|
110
|
+
export { type BaseOtpOptions as B, type CleanupOtpOptions as C, type OtpEmailSender as O, type RequestOtpOptions as R, type SendgridSenderOptions as S, type VerifyOtpOptions as V, type RequestOtpPayload as a, type RequestOtpResponse as b, type VerifyOtpPayload as c, type VerifyOtpResponse as d, type OtpEmailInput as e, type OtpEmail as f, OTP_ERROR_CODES as g, type OtpDocumentData as h, type OtpErrorCode as i, type OtpProvisioner as j };
|
package/package.json
CHANGED
|
@@ -1,6 +1,93 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guettonenrique/passwordless-auth",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Passwordless email-OTP authentication: Firebase Cloud Function factories + React Native API and UI. One package, two entries, zero shared runtime deps.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
"./package.json": "./package.json",
|
|
9
|
+
"./shared": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/shared/index.d.ts",
|
|
12
|
+
"default": "./dist/shared/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/shared/index.d.cts",
|
|
16
|
+
"default": "./dist/shared/index.cjs"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"./functions": {
|
|
20
|
+
"import": {
|
|
21
|
+
"types": "./dist/functions/index.d.cts",
|
|
22
|
+
"default": "./dist/functions/index.cjs"
|
|
23
|
+
},
|
|
24
|
+
"require": {
|
|
25
|
+
"types": "./dist/functions/index.d.cts",
|
|
26
|
+
"default": "./dist/functions/index.cjs"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"./react-native": {
|
|
30
|
+
"import": {
|
|
31
|
+
"types": "./dist/react-native/index.d.ts",
|
|
32
|
+
"default": "./dist/react-native/index.js"
|
|
33
|
+
},
|
|
34
|
+
"default": {
|
|
35
|
+
"types": "./dist/react-native/index.d.ts",
|
|
36
|
+
"default": "./dist/react-native/index.js"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"LICENSE",
|
|
43
|
+
"README.md"
|
|
44
|
+
],
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "git+https://github.com/guettonenrique/passwordless-auth.git"
|
|
48
|
+
},
|
|
49
|
+
"publishConfig": {
|
|
50
|
+
"registry": "https://registry.npmjs.org",
|
|
51
|
+
"access": "public"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "tsup",
|
|
55
|
+
"prepublishOnly": "npm run build",
|
|
56
|
+
"typecheck": "tsc --noEmit -p tsconfig.shared.json && tsc --noEmit -p tsconfig.functions.json && tsc --noEmit -p tsconfig.react-native.json",
|
|
57
|
+
"lint": "eslint .",
|
|
58
|
+
"test": "vitest run",
|
|
59
|
+
"clean": "rm -rf dist"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@eslint/js": "^9.30.0",
|
|
63
|
+
"@react-native-firebase/app": "^27.1.0",
|
|
64
|
+
"@react-native-firebase/auth": "^27.1.0",
|
|
65
|
+
"@react-native-firebase/functions": "^27.1.0",
|
|
66
|
+
"@sendgrid/mail": "^8.1.5",
|
|
67
|
+
"@types/node": "^24.0.0",
|
|
68
|
+
"@types/react": "^19.0.0",
|
|
69
|
+
"@types/react-test-renderer": "^19.3.1",
|
|
70
|
+
"eslint": "^9.30.0",
|
|
71
|
+
"expo-haptics": "~58.0.7",
|
|
72
|
+
"firebase-admin": "^14.2.0",
|
|
73
|
+
"firebase-functions": "^7.3.2",
|
|
74
|
+
"lucide-react-native": "^1.71.0",
|
|
75
|
+
"react": "19.3.0",
|
|
76
|
+
"react-native": "0.88.1",
|
|
77
|
+
"react-native-keyboard-controller": "1.22.7",
|
|
78
|
+
"react-test-renderer": "19.3.0",
|
|
79
|
+
"tsup": "^8.0.0",
|
|
80
|
+
"typescript": "^5.7.3",
|
|
81
|
+
"typescript-eslint": "^8.35.0",
|
|
82
|
+
"vitest": "^3.2.0"
|
|
83
|
+
},
|
|
84
|
+
"engines": {
|
|
85
|
+
"node": ">=20"
|
|
86
|
+
},
|
|
87
|
+
"allowScripts": {
|
|
88
|
+
"esbuild@0.27.7": true,
|
|
89
|
+
"@firebase/util@1.15.3": true,
|
|
90
|
+
"fsevents@2.3.3": true,
|
|
91
|
+
"protobufjs@7.6.6": true
|
|
92
|
+
}
|
|
93
|
+
}
|