@epic-web/workshop-app 5.9.2 → 5.9.3

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.
@@ -71,8 +71,7 @@ import { useEventSource } from "remix-utils/sse/react";
71
71
  import { eventStream } from "remix-utils/sse/server";
72
72
  import { EventEmitter } from "events";
73
73
  import { remember } from "@epic-web/remember";
74
- import md5 from "md5-hex";
75
- import { Issuer } from "openid-client";
74
+ import * as client from "openid-client";
76
75
  import inspector from "node:inspector";
77
76
  import { getCommitInfo, getLatestWorkshopAppVersion } from "@epic-web/workshop-utils/git.server";
78
77
  import { Resvg } from "@resvg/resvg-js";
@@ -9773,6 +9772,11 @@ const EVENTS = {
9773
9772
  AUTH_RESOLVED: "AUTH_RESOLVED",
9774
9773
  AUTH_REJECTED: "AUTH_REJECTED"
9775
9774
  };
9775
+ const UserInfoSchema = z.object({
9776
+ id: z.string(),
9777
+ email: z.string().optional(),
9778
+ name: z.string().optional()
9779
+ });
9776
9780
  const authEmitter = remember("authEmitter", () => new EventEmitter());
9777
9781
  authEmitter.removeAllListeners();
9778
9782
  async function registerDevice() {
@@ -9780,47 +9784,55 @@ async function registerDevice() {
9780
9784
  product: { host }
9781
9785
  } = getWorkshopConfig();
9782
9786
  const { ISSUER = `https://${host}/oauth` } = process.env;
9783
- const GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
9784
9787
  try {
9785
- const issuer = await Issuer.discover(ISSUER);
9786
- const client = await issuer.Client.register({
9787
- grant_types: [GRANT_TYPE],
9788
- response_types: [],
9789
- redirect_uris: [],
9790
- token_endpoint_auth_method: "none",
9791
- application_type: "native"
9792
- });
9793
- const handle2 = await client.deviceAuthorization();
9788
+ const config = await client.discovery(new URL(ISSUER), "EPICSHOP_APP");
9789
+ const deviceResponse = await client.initiateDeviceAuthorization(config, {});
9794
9790
  authEmitter.emit(EVENTS.USER_CODE_RECEIVED, {
9795
- code: handle2.user_code,
9796
- url: handle2.verification_uri_complete
9791
+ code: deviceResponse.user_code,
9792
+ url: deviceResponse.verification_uri_complete
9797
9793
  });
9798
- const timeout = setTimeout(() => handle2.abort(), handle2.expires_in * 1e3);
9799
- const tokenSet = await handle2.poll().catch(() => {
9800
- });
9801
- clearTimeout(timeout);
9802
- if (!tokenSet) {
9803
- authEmitter.emit(EVENTS.AUTH_REJECTED, {
9804
- error: `Timed out in ${handle2.expires_in} seconds waiting for user to authorize device.`
9794
+ const timeout = setTimeout(() => {
9795
+ throw new Error("Device authorization timed out");
9796
+ }, deviceResponse.expires_in * 1e3);
9797
+ try {
9798
+ const tokenSet = await client.pollDeviceAuthorizationGrant(
9799
+ config,
9800
+ deviceResponse
9801
+ );
9802
+ clearTimeout(timeout);
9803
+ if (!tokenSet) {
9804
+ authEmitter.emit(EVENTS.AUTH_REJECTED, {
9805
+ error: "No token set"
9806
+ });
9807
+ return;
9808
+ }
9809
+ const protectedResourceResponse = await client.fetchProtectedResource(
9810
+ config,
9811
+ tokenSet.access_token,
9812
+ new URL(`${ISSUER}/userinfo`),
9813
+ "GET"
9814
+ );
9815
+ const userinfoRaw = await protectedResourceResponse.json();
9816
+ const userinfoResult = UserInfoSchema.safeParse(userinfoRaw);
9817
+ if (!userinfoResult.success) {
9818
+ authEmitter.emit(EVENTS.AUTH_REJECTED, {
9819
+ error: `Failed to parse user info: ${userinfoResult.error.message}`
9820
+ });
9821
+ return;
9822
+ }
9823
+ const userinfo = userinfoResult.data;
9824
+ await setAuthInfo({
9825
+ id: userinfo.id,
9826
+ tokenSet,
9827
+ email: userinfo.email,
9828
+ name: userinfo.name
9805
9829
  });
9806
- return;
9830
+ await getUserInfo({ forceFresh: true });
9831
+ authEmitter.emit(EVENTS.AUTH_RESOLVED);
9832
+ } catch (error) {
9833
+ clearTimeout(timeout);
9834
+ throw error;
9807
9835
  }
9808
- const userinfo = await client.userinfo(tokenSet);
9809
- let id;
9810
- if (typeof userinfo.id === "string") {
9811
- id = userinfo.id;
9812
- } else {
9813
- console.warn("[UNEXPECTED] User ID is not a string:", userinfo.id);
9814
- id = userinfo.email ? md5(userinfo.email) : createId();
9815
- }
9816
- await setAuthInfo({
9817
- id,
9818
- tokenSet,
9819
- email: userinfo.email,
9820
- name: userinfo.name
9821
- });
9822
- await getUserInfo({ forceFresh: true });
9823
- authEmitter.emit(EVENTS.AUTH_RESOLVED);
9824
9836
  } catch (error) {
9825
9837
  authEmitter.emit(EVENTS.AUTH_REJECTED, {
9826
9838
  error: getErrorMessage(error)