@dialtribe/auth 0.1.0 → 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/README.md CHANGED
@@ -53,6 +53,10 @@ betterAuth({
53
53
  dialtribeProvider({
54
54
  clientId: process.env.DIALTRIBE_OIDC_CLIENT_ID!,
55
55
  clientSecret: process.env.DIALTRIBE_OIDC_CLIENT_SECRET!,
56
+ // Optional: name to use when Dialtribe sends none (email-code
57
+ // identities have no name). String or (async) function.
58
+ // Omit for a random `member-xxxxxxxx`.
59
+ fallbackName: () => myRandomHandle(),
56
60
  }), // pkce: true baked in
57
61
  ],
58
62
  }),
@@ -60,6 +64,10 @@ betterAuth({
60
64
  });
61
65
  ```
62
66
 
67
+ `dialtribeProvider` maps the profile for you: a missing name uses
68
+ `fallbackName` (never anything from the email), and the email only counts as
69
+ verified when Dialtribe sends `email_verified: true`.
70
+
63
71
  ```ts
64
72
  // app/api/auth/backchannel-logout/route.ts
65
73
  import { createBackchannelLogoutHandler } from "@dialtribe/auth/server";
package/dist/server.d.ts CHANGED
@@ -20,12 +20,23 @@ export interface DialtribeProviderOptions {
20
20
  discoveryUrl?: string;
21
21
  /** Extra scopes on top of openid/email/profile. */
22
22
  extraScopes?: string[];
23
+ /**
24
+ * Name to use when Dialtribe sends none. Identities created by email code
25
+ * have an empty name, and better-auth rejects an empty name
26
+ * (`name_is_missing`). Pass a string or a function to use your own naming
27
+ * style; omit it to get a random `member-xxxxxxxx`. Only used locally in
28
+ * your app; it is never sent back to Dialtribe.
29
+ */
30
+ fallbackName?: string | (() => string | Promise<string>);
23
31
  }
24
32
  /**
25
33
  * The better-auth `genericOAuth` provider config for Dialtribe, with PKCE baked
26
34
  * in (the Dialtribe provider requires it). Spread into the plugin:
27
35
  *
28
36
  * genericOAuth({ config: [dialtribeProvider({ clientId, clientSecret })] })
37
+ *
38
+ * It also maps the profile: a missing name falls back to `fallbackName`, and
39
+ * the email only counts as verified when Dialtribe says `email_verified: true`.
29
40
  */
30
41
  export declare function dialtribeProvider(opts: DialtribeProviderOptions): {
31
42
  providerId: string;
@@ -34,6 +45,10 @@ export declare function dialtribeProvider(opts: DialtribeProviderOptions): {
34
45
  clientSecret: string;
35
46
  scopes: string[];
36
47
  pkce: true;
48
+ mapProfileToUser: (profile: Record<string, unknown>) => Promise<{
49
+ name: string;
50
+ emailVerified: boolean;
51
+ }>;
37
52
  };
38
53
  /**
39
54
  * Recommended top-level better-auth `account` options for a Dialtribe client.
package/dist/server.js CHANGED
@@ -23,11 +23,24 @@ export async function getServiceOnlineCount(opts) {
23
23
  const data = (await res.json());
24
24
  return { users: data.users ?? 0, clients: data.clients ?? 0 };
25
25
  }
26
+ /** Random, non-identifying default name (never derived from the email). */
27
+ function defaultFallbackName() {
28
+ const bytes = new Uint8Array(4);
29
+ globalThis.crypto.getRandomValues(bytes);
30
+ return `member-${Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("")}`;
31
+ }
32
+ async function resolveFallbackName(fallback) {
33
+ const value = typeof fallback === "function" ? await fallback() : fallback;
34
+ return (typeof value === "string" && value.trim()) || defaultFallbackName();
35
+ }
26
36
  /**
27
37
  * The better-auth `genericOAuth` provider config for Dialtribe, with PKCE baked
28
38
  * in (the Dialtribe provider requires it). Spread into the plugin:
29
39
  *
30
40
  * genericOAuth({ config: [dialtribeProvider({ clientId, clientSecret })] })
41
+ *
42
+ * It also maps the profile: a missing name falls back to `fallbackName`, and
43
+ * the email only counts as verified when Dialtribe says `email_verified: true`.
31
44
  */
32
45
  export function dialtribeProvider(opts) {
33
46
  return {
@@ -37,6 +50,13 @@ export function dialtribeProvider(opts) {
37
50
  clientSecret: opts.clientSecret,
38
51
  scopes: ["openid", "email", "profile", ...(opts.extraScopes ?? [])],
39
52
  pkce: true,
53
+ mapProfileToUser: async (profile) => {
54
+ const name = typeof profile.name === "string" ? profile.name.trim() : "";
55
+ return {
56
+ name: name || (await resolveFallbackName(opts.fallbackName)),
57
+ emailVerified: profile.email_verified === true,
58
+ };
59
+ },
40
60
  };
41
61
  }
42
62
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dialtribe/auth",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Relying-party SDK for Dialtribe Identity (OIDC SSO): sign-in, global sign-out, guest-work resume, and back-channel logout.",
5
5
  "type": "module",
6
6
  "sideEffects": false,