@openstax/ts-utils 1.16.2 → 1.18.0

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.
@@ -26,6 +26,7 @@ export interface Window {
26
26
  addEventListener: (event: 'message', callback: EventHandler) => void;
27
27
  removeEventListener: (event: 'message', callback: EventHandler) => void;
28
28
  }
29
+ export declare type UpdatableUserFields = Partial<Pick<User, 'consent_preferences' | 'first_name' | 'last_name'>>;
29
30
  export declare const browserAuthProvider: <C extends string = "auth">({ window, configSpace }: Initializer<C>) => (configProvider: { [key in C]: {
30
31
  accountsBase: import("../../config").ConfigValueProvider<string>;
31
32
  }; }) => {
@@ -62,5 +63,12 @@ export declare const browserAuthProvider: <C extends string = "auth">({ window,
62
63
  * loads current user identity. does not reflect changes in identity after being called the first time.
63
64
  */
64
65
  getUser: () => Promise<User | undefined>;
66
+ /**
67
+ * updates user settings, for example the cookie consent preferences
68
+ */
69
+ updateUser: (updates: UpdatableUserFields) => Promise<{
70
+ user: User;
71
+ token: string | null;
72
+ }>;
65
73
  };
66
74
  export {};
@@ -1,7 +1,7 @@
1
1
  import { once } from '../..';
2
2
  import { resolveConfigValue } from '../../config';
3
3
  import { ifDefined } from '../../guards';
4
- import { unsafePayloadValidator } from '../../routing/helpers';
4
+ import { METHOD, unsafePayloadValidator } from '../../routing';
5
5
  import { embeddedAuthProvider, PostMessageTypes } from './utils/embeddedAuthProvider';
6
6
  const isUserData = unsafePayloadValidator();
7
7
  export const browserAuthProvider = ({ window, configSpace }) => (configProvider) => {
@@ -99,6 +99,17 @@ export const browserAuthProvider = ({ window, configSpace }) => (configProvider)
99
99
  const getUser = async () => {
100
100
  return (await getUserData()).user;
101
101
  };
102
+ const updateUser = async (updates) => {
103
+ const response = await window.fetch((await accountsBase()).replace(/\/+$/, '') + '/api/user', { ...getAuthorizedFetchConfigFromData(userData), method: METHOD.PUT, body: JSON.stringify(updates) });
104
+ if (response.status === 200) {
105
+ const user = await response.json();
106
+ if (isUserData(user)) {
107
+ return { ...userData, user };
108
+ }
109
+ }
110
+ const message = await response.text();
111
+ throw new Error(`Error response from Accounts ${response.status}: ${message}`);
112
+ };
102
113
  return {
103
114
  /**
104
115
  * gets the authentication token
@@ -131,5 +142,9 @@ export const browserAuthProvider = ({ window, configSpace }) => (configProvider)
131
142
  * loads current user identity. does not reflect changes in identity after being called the first time.
132
143
  */
133
144
  getUser,
145
+ /**
146
+ * updates user settings, for example the cookie consent preferences
147
+ */
148
+ updateUser,
134
149
  };
135
150
  };
@@ -30,7 +30,9 @@ export interface ApiUser extends TokenUser {
30
30
  }>;
31
31
  external_ids: string[];
32
32
  is_not_gdpr_location: boolean;
33
+ self_reported_role: string;
33
34
  signed_contract_names: string[];
35
+ using_openstax: boolean;
34
36
  }
35
37
  export declare type User = TokenUser | ApiUser;
36
38
  export declare type AuthProvider = {
@@ -21,7 +21,7 @@ export declare const createLaunchSigner: <C extends string = "launch">({ configS
21
21
  jwks: () => Promise<{
22
22
  keys: JWK.RawKey[];
23
23
  }>;
24
- sign: (subject: string, maxExpiresIn?: string | number | null | undefined) => Promise<string>;
24
+ sign: (subject: string, maxExp?: number | null | undefined) => Promise<string>;
25
25
  };
26
26
  export declare type LaunchSigner = ReturnType<ReturnType<typeof createLaunchSigner>>;
27
27
  export {};
@@ -28,17 +28,21 @@ export const createLaunchSigner = ({ configSpace }) => (configProvider) => {
28
28
  return keystore;
29
29
  });
30
30
  const jwks = async () => (await getKeyStore()).toJSON(false);
31
- const getExpiresInWithMax = async (maxExpiresIn) => {
31
+ const getExpiresInWithMax = async (maxExp) => {
32
32
  const expiresIn = await getExpiresIn();
33
- const maxExpiresInSeconds = typeof maxExpiresIn === 'number' ? maxExpiresIn :
34
- typeof maxExpiresIn === 'string' ? Math.floor(ms(maxExpiresIn) / 1000) :
35
- undefined;
36
- return maxExpiresInSeconds ? Math.min(Math.floor(ms(expiresIn) / 1000), maxExpiresInSeconds) : expiresIn;
33
+ // The ms library used by jsonwebtoken can handle a value in seconds as well as a string like '1d'
34
+ if (!maxExp) {
35
+ return expiresIn;
36
+ }
37
+ // Convert both values to seconds for comparison
38
+ const expiresInSeconds = Math.floor(ms(expiresIn) / 1000);
39
+ const maxExpSeconds = maxExp - Math.floor(Date.now() / 1000);
40
+ return Math.min(expiresInSeconds, maxExpSeconds);
37
41
  };
38
- const sign = async (subject, maxExpiresIn) => {
42
+ const sign = async (subject, maxExp) => {
39
43
  const alg = await getAlg();
40
44
  // expiresIn can be a number of seconds or a string like '1h' or '1d'
41
- const expiresIn = await getExpiresInWithMax(maxExpiresIn);
45
+ const expiresIn = await getExpiresInWithMax(maxExp);
42
46
  const iss = await getIss();
43
47
  const header = { alg, iss };
44
48
  return jwt.sign({}, await getPrivateKey(), { algorithm: alg, expiresIn, header, issuer: iss, subject });