@oglofus/auth 1.0.1 → 1.1.1
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/README.md +33 -14
- package/dist/core/auth.d.ts +7 -6
- package/dist/core/auth.js +238 -39
- package/dist/core/utils.d.ts +1 -0
- package/dist/core/utils.js +2 -1
- package/dist/core/validators.js +1 -1
- package/dist/errors/index.d.ts +2 -3
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/plugins/email-otp.js +31 -18
- package/dist/plugins/index.d.ts +3 -2
- package/dist/plugins/index.js +3 -2
- package/dist/plugins/magic-link.js +15 -24
- package/dist/plugins/oauth2.d.ts +8 -1
- package/dist/plugins/oauth2.js +72 -39
- package/dist/plugins/organizations.d.ts +1 -1
- package/dist/plugins/organizations.js +58 -9
- package/dist/plugins/passkey.js +22 -31
- package/dist/plugins/password.js +4 -7
- package/dist/plugins/stripe.d.ts +19 -0
- package/dist/plugins/stripe.js +583 -0
- package/dist/plugins/two-factor.js +3 -6
- package/dist/types/adapters.d.ts +58 -23
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +2 -2
- package/dist/types/model.d.ts +86 -13
- package/dist/types/plugins.d.ts +91 -5
- package/dist/types/results.d.ts +1 -1
- package/dist/types/results.js +11 -2
- package/package.json +10 -3
package/dist/plugins/passkey.js
CHANGED
|
@@ -1,45 +1,34 @@
|
|
|
1
|
+
import { cloneWithout, createId } from "../core/utils.js";
|
|
2
|
+
import { ensureFields } from "../core/validators.js";
|
|
1
3
|
import { AuthError } from "../errors/index.js";
|
|
2
4
|
import { createIssue } from "../issues/index.js";
|
|
3
5
|
import { errorOperation, successOperation } from "../types/results.js";
|
|
4
|
-
import { cloneWithout, createId } from "../core/utils.js";
|
|
5
|
-
import { ensureFields } from "../core/validators.js";
|
|
6
|
-
const getString = (obj, key) => {
|
|
7
|
-
const value = obj[key];
|
|
8
|
-
return typeof value === "string" && value.length > 0 ? value : null;
|
|
9
|
-
};
|
|
10
|
-
const getNumber = (obj, key) => {
|
|
11
|
-
const value = obj[key];
|
|
12
|
-
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
13
|
-
};
|
|
14
6
|
export const passkeyPlugin = (config) => ({
|
|
15
7
|
kind: "auth_method",
|
|
16
8
|
method: "passkey",
|
|
17
|
-
version: "
|
|
9
|
+
version: "2.0.0",
|
|
18
10
|
supports: {
|
|
19
11
|
register: true,
|
|
20
12
|
},
|
|
21
13
|
issueFields: {
|
|
22
|
-
authenticate: ["
|
|
23
|
-
register: ["email", "
|
|
14
|
+
authenticate: ["authentication"],
|
|
15
|
+
register: ["email", "registration", ...config.requiredProfileFields.map(String)],
|
|
24
16
|
},
|
|
25
17
|
authenticate: async (ctx, input) => {
|
|
26
|
-
const credentialId =
|
|
18
|
+
const credentialId = input.authentication.credentialId;
|
|
27
19
|
if (!credentialId) {
|
|
28
|
-
return errorOperation(new AuthError("PASSKEY_INVALID_ASSERTION", "Credential id missing from
|
|
29
|
-
createIssue("credentialId is required", ["
|
|
20
|
+
return errorOperation(new AuthError("PASSKEY_INVALID_ASSERTION", "Credential id missing from verified passkey authentication.", 400, [
|
|
21
|
+
createIssue("credentialId is required", ["authentication", "credentialId"]),
|
|
30
22
|
]));
|
|
31
23
|
}
|
|
32
24
|
const credential = await config.passkeys.findByCredentialId(credentialId);
|
|
33
25
|
if (!credential) {
|
|
34
26
|
return errorOperation(new AuthError("PASSKEY_INVALID_ASSERTION", "Unknown passkey credential.", 400));
|
|
35
27
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
if (counter <= credential.counter) {
|
|
39
|
-
return errorOperation(new AuthError("PASSKEY_INVALID_ASSERTION", "Passkey counter regression detected.", 400));
|
|
40
|
-
}
|
|
41
|
-
await config.passkeys.updateCounter(credential.credentialId, counter);
|
|
28
|
+
if (input.authentication.nextCounter <= credential.counter) {
|
|
29
|
+
return errorOperation(new AuthError("PASSKEY_INVALID_ASSERTION", "Passkey counter regression detected.", 400));
|
|
42
30
|
}
|
|
31
|
+
await config.passkeys.updateCounter(credential.credentialId, input.authentication.nextCounter);
|
|
43
32
|
const user = await ctx.adapters.users.findById(credential.userId);
|
|
44
33
|
if (!user) {
|
|
45
34
|
return errorOperation(new AuthError("USER_NOT_FOUND", "User not found.", 404));
|
|
@@ -51,20 +40,21 @@ export const passkeyPlugin = (config) => ({
|
|
|
51
40
|
if (requiredError) {
|
|
52
41
|
return errorOperation(requiredError);
|
|
53
42
|
}
|
|
54
|
-
const credentialId =
|
|
55
|
-
const publicKey = getString(input.attestation, "publicKey");
|
|
56
|
-
const counter = getNumber(input.attestation, "counter") ?? 0;
|
|
43
|
+
const { credentialId, publicKey, counter, transports } = input.registration;
|
|
57
44
|
if (!credentialId || !publicKey) {
|
|
58
|
-
return errorOperation(new AuthError("PASSKEY_INVALID_ATTESTATION", "Invalid passkey
|
|
59
|
-
createIssue("credentialId/publicKey is required", ["
|
|
45
|
+
return errorOperation(new AuthError("PASSKEY_INVALID_ATTESTATION", "Invalid verified passkey registration.", 400, [
|
|
46
|
+
createIssue("credentialId/publicKey is required", ["registration"]),
|
|
47
|
+
]));
|
|
48
|
+
}
|
|
49
|
+
const existingCredential = await config.passkeys.findByCredentialId(credentialId);
|
|
50
|
+
if (existingCredential) {
|
|
51
|
+
return errorOperation(new AuthError("CONFLICT", "Passkey credential already exists.", 409, [
|
|
52
|
+
createIssue("credentialId already registered", ["registration", "credentialId"]),
|
|
60
53
|
]));
|
|
61
54
|
}
|
|
62
55
|
let user = await ctx.adapters.users.findByEmail(input.email);
|
|
63
56
|
if (!user) {
|
|
64
|
-
const payload = cloneWithout(input, [
|
|
65
|
-
"method",
|
|
66
|
-
"attestation",
|
|
67
|
-
]);
|
|
57
|
+
const payload = cloneWithout(input, ["method", "registration"]);
|
|
68
58
|
payload.emailVerified = true;
|
|
69
59
|
user = await ctx.adapters.users.create(payload);
|
|
70
60
|
}
|
|
@@ -74,6 +64,7 @@ export const passkeyPlugin = (config) => ({
|
|
|
74
64
|
credentialId,
|
|
75
65
|
publicKey,
|
|
76
66
|
counter,
|
|
67
|
+
transports,
|
|
77
68
|
createdAt: ctx.now(),
|
|
78
69
|
});
|
|
79
70
|
return successOperation({ user });
|
package/dist/plugins/password.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import { cloneWithout, secretHash, secretVerify } from "../core/utils.js";
|
|
2
|
+
import { ensureFields } from "../core/validators.js";
|
|
1
3
|
import { AuthError } from "../errors/index.js";
|
|
2
4
|
import { createIssue } from "../issues/index.js";
|
|
3
5
|
import { errorOperation, successOperation } from "../types/results.js";
|
|
4
|
-
import { cloneWithout, secretHash, secretVerify } from "../core/utils.js";
|
|
5
|
-
import { ensureFields } from "../core/validators.js";
|
|
6
6
|
export const passwordPlugin = (config) => ({
|
|
7
7
|
kind: "auth_method",
|
|
8
8
|
method: "password",
|
|
9
|
-
version: "
|
|
9
|
+
version: "2.0.0",
|
|
10
10
|
supports: {
|
|
11
11
|
register: true,
|
|
12
12
|
},
|
|
@@ -25,10 +25,7 @@ export const passwordPlugin = (config) => ({
|
|
|
25
25
|
if (requiredError) {
|
|
26
26
|
return errorOperation(requiredError);
|
|
27
27
|
}
|
|
28
|
-
const payload = cloneWithout(input, [
|
|
29
|
-
"method",
|
|
30
|
-
"password",
|
|
31
|
-
]);
|
|
28
|
+
const payload = cloneWithout(input, ["method", "password"]);
|
|
32
29
|
if (payload.emailVerified === undefined) {
|
|
33
30
|
payload.emailVerified = false;
|
|
34
31
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type Stripe from "stripe";
|
|
2
|
+
import type { StripeCustomerAdapter, StripeSubscriptionAdapter, StripeTrialUsageAdapter, StripeWebhookEventAdapter } from "../types/adapters.js";
|
|
3
|
+
import type { UserBase } from "../types/model.js";
|
|
4
|
+
import type { DomainPlugin, StripePlansResolver, StripePluginApi } from "../types/plugins.js";
|
|
5
|
+
type StripePluginHandlers<Feature extends string, LimitKey extends string> = {
|
|
6
|
+
customers: StripeCustomerAdapter;
|
|
7
|
+
subscriptions: StripeSubscriptionAdapter<Feature, LimitKey>;
|
|
8
|
+
events: StripeWebhookEventAdapter;
|
|
9
|
+
trials?: StripeTrialUsageAdapter;
|
|
10
|
+
};
|
|
11
|
+
export type StripePluginConfig<U extends UserBase, Feature extends string, LimitKey extends string> = {
|
|
12
|
+
stripe: Stripe;
|
|
13
|
+
webhookSecret: string;
|
|
14
|
+
plans: StripePlansResolver<Feature, LimitKey>;
|
|
15
|
+
handlers: StripePluginHandlers<Feature, LimitKey>;
|
|
16
|
+
customerMode?: "user" | "organization" | "both";
|
|
17
|
+
};
|
|
18
|
+
export declare const stripePlugin: <U extends UserBase, Feature extends string, LimitKey extends string>(config: StripePluginConfig<U, Feature, LimitKey>) => DomainPlugin<"stripe", U, StripePluginApi<Feature, LimitKey>>;
|
|
19
|
+
export {};
|