authhero 0.2.0 → 0.2.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.
@@ -0,0 +1,130 @@
1
+ import { User, UserDataAdapter } from "@authhero/adapter-interfaces";
2
+
3
+ export async function getUsersByEmail(
4
+ userAdapter: UserDataAdapter,
5
+ tenantId: string,
6
+ email: string,
7
+ ): Promise<User[]> {
8
+ const response = await userAdapter.list(tenantId, {
9
+ page: 0,
10
+ per_page: 10,
11
+ include_totals: false,
12
+ q: `email:${email}`,
13
+ });
14
+
15
+ return response.users;
16
+ }
17
+
18
+ interface GetUserByEmailAndProviderParams {
19
+ userAdapter: UserDataAdapter;
20
+ tenant_id: string;
21
+ email: string;
22
+ provider: string;
23
+ }
24
+
25
+ export async function getUserByEmailAndProvider({
26
+ userAdapter,
27
+ tenant_id,
28
+ email,
29
+ provider,
30
+ }: GetUserByEmailAndProviderParams): Promise<User | null> {
31
+ const { users } = await userAdapter.list(tenant_id, {
32
+ page: 0,
33
+ per_page: 10,
34
+ include_totals: false,
35
+ q: `email:${email} provider:${provider}`,
36
+ });
37
+
38
+ if (users.length > 1) {
39
+ console.error("More than one user found for same email and provider");
40
+ }
41
+
42
+ return users[0] || null;
43
+ }
44
+
45
+ interface GetPrimaryUserByEmailParams {
46
+ userAdapter: UserDataAdapter;
47
+ tenant_id: string;
48
+ email: string;
49
+ }
50
+
51
+ export async function getPrimaryUserByEmail({
52
+ userAdapter,
53
+ tenant_id,
54
+ email,
55
+ }: GetPrimaryUserByEmailParams): Promise<User | undefined> {
56
+ const { users: usersWithUnverifiedPasswordAccounts } = await userAdapter.list(
57
+ tenant_id,
58
+ {
59
+ page: 0,
60
+ per_page: 10,
61
+ include_totals: false,
62
+ q: `email:${email}`,
63
+ },
64
+ );
65
+
66
+ // filter out unverified accounts
67
+ const users = usersWithUnverifiedPasswordAccounts.filter(
68
+ // maybe we should do this for all providers
69
+ (user) => !(user.provider === "auth2" && !user.email_verified),
70
+ );
71
+
72
+ if (users.length === 0) {
73
+ return;
74
+ }
75
+
76
+ const primaryUsers = users.filter((user) => !user.linked_to);
77
+
78
+ if (primaryUsers.length > 0) {
79
+ if (primaryUsers.length > 1) {
80
+ console.error("More than one primary user found for same email");
81
+ }
82
+
83
+ return primaryUsers[0];
84
+ }
85
+
86
+ // so now we have only linked users for this email address
87
+
88
+ // I am going to assume that all the linked users with the same email address
89
+ // are linked to the same primary account
90
+
91
+ const primaryAccount = await userAdapter.get(tenant_id, users[0]?.linked_to!);
92
+
93
+ if (!primaryAccount) {
94
+ // this is a real error where we should interrupt the flow
95
+ throw new Error("Primary account not found");
96
+ }
97
+
98
+ return primaryAccount;
99
+ }
100
+
101
+ interface GetPrimaryUserByEmailAndProviderParams {
102
+ userAdapter: UserDataAdapter;
103
+ tenant_id: string;
104
+ email: string;
105
+ provider: string;
106
+ }
107
+
108
+ export async function getPrimaryUserByEmailAndProvider({
109
+ userAdapter,
110
+ tenant_id,
111
+ email,
112
+ provider,
113
+ }: GetPrimaryUserByEmailAndProviderParams): Promise<User | null> {
114
+ const user = await getUserByEmailAndProvider({
115
+ userAdapter,
116
+ tenant_id,
117
+ email,
118
+ provider,
119
+ });
120
+
121
+ if (!user) {
122
+ return null;
123
+ }
124
+
125
+ if (!user.linked_to) {
126
+ return user;
127
+ }
128
+
129
+ return userAdapter.get(tenant_id, user.linked_to);
130
+ }
package/vite.config.ts CHANGED
@@ -24,7 +24,7 @@ const formats = Object.keys(fileName) as Array<keyof typeof fileName>;
24
24
  module.exports = defineConfig({
25
25
  base: "./",
26
26
  build: {
27
- outDir: "./build/dist",
27
+ outDir: "./dist",
28
28
  lib: {
29
29
  entry: path.resolve(__dirname, "src/index.ts"),
30
30
  name: getPackageNameCamelCase(),
package/src/bun.ts DELETED
@@ -1,16 +0,0 @@
1
- import { OpenAPIHono } from "@hono/zod-openapi";
2
- import { Bindings } from "./types/Bindings";
3
- import { Context } from "hono";
4
- import { init } from "./";
5
-
6
- const app = new OpenAPIHono<{ Bindings: Bindings }>();
7
-
8
- const authhero = init();
9
-
10
- app.get("/test", (ctx: Context) => {
11
- return ctx.text("Hello, world!");
12
- });
13
-
14
- app.route("/", authhero);
15
-
16
- export default app;
package/src/types/JWKS.ts DELETED
@@ -1,37 +0,0 @@
1
- import { z } from "@hono/zod-openapi";
2
-
3
- export const jwksSchema = z.object({
4
- alg: z.string(),
5
- e: z.string(),
6
- kid: z.string(),
7
- kty: z.string(),
8
- n: z.string(),
9
- use: z.string().optional(),
10
- });
11
-
12
- export const jwksKeySchema = z.object({
13
- keys: z.array(jwksSchema),
14
- });
15
-
16
- export const openIDConfigurationSchema = z.object({
17
- issuer: z.string(),
18
- authorization_endpoint: z.string(),
19
- token_endpoint: z.string(),
20
- device_authorization_endpoint: z.string(),
21
- userinfo_endpoint: z.string(),
22
- mfa_challenge_endpoint: z.string(),
23
- jwks_uri: z.string(),
24
- registration_endpoint: z.string(),
25
- revocation_endpoint: z.string(),
26
- scopes_supported: z.array(z.string()),
27
- response_types_supported: z.array(z.string()),
28
- code_challenge_methods_supported: z.array(z.string()),
29
- response_modes_supported: z.array(z.string()),
30
- subject_types_supported: z.array(z.string()),
31
- id_token_signing_alg_values_supported: z.array(z.string()),
32
- token_endpoint_auth_methods_supported: z.array(z.string()),
33
- claims_supported: z.array(z.string()),
34
- request_uri_parameter_supported: z.boolean(),
35
- request_parameter_supported: z.boolean(),
36
- token_endpoint_auth_signing_alg_values_supported: z.array(z.string()),
37
- });