Skip to content

Commit

Permalink
chore: getUser with TS generics for custom properties
Browse files Browse the repository at this point in the history
  • Loading branch information
peterphanouvong committed Aug 25, 2024
1 parent abdf68c commit 809fced
Show file tree
Hide file tree
Showing 10 changed files with 53 additions and 109 deletions.
3 changes: 2 additions & 1 deletion clientConfig/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ const packageJson = require('./package.json');

import babel from '@rollup/plugin-babel';
import {terser} from 'rollup-plugin-terser';
import tsPlugin from '@rollup/plugin-typescript';

export default {
plugins: [babel({babelHelpers: 'bundled'}), terser()],
plugins: [babel({babelHelpers: 'bundled'}), terser(), tsPlugin()],
input: './src/index.js',
output: [
{
Expand Down
3 changes: 2 additions & 1 deletion componentConfig/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import babel from '@rollup/plugin-babel';
import {terser} from 'rollup-plugin-terser';
import tsPlugin from '@rollup/plugin-typescript';

export default {
plugins: [babel({babelHelpers: 'bundled'}), terser()],
plugins: [babel({babelHelpers: 'bundled'}), terser(), tsPlugin()],
input: 'src/components/index.js',
output: [
{
Expand Down
3 changes: 2 additions & 1 deletion middlewareConfig/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import babel from '@rollup/plugin-babel';
import {terser} from 'rollup-plugin-terser';
import tsPlugin from '@rollup/plugin-typescript';

export default {
plugins: [babel({babelHelpers: 'bundled'}), terser()],
plugins: [babel({babelHelpers: 'bundled'}), terser(), tsPlugin()],
input: 'src/middleware/index.js',
output: [
{
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
"@babel/preset-react": "^7.17.12",
"@babel/preset-typescript": "^7.23.3",
"@rollup/plugin-babel": "^5.3.1",
"@rollup/plugin-typescript": "^11.1.5",
"@rollup/plugin-typescript": "^11.1.6",
"@testing-library/react": "^14.2.1",
"@types/cookie": "^0.5.3",
"@types/jest": "^29.5.12",
Expand Down
3 changes: 2 additions & 1 deletion serverConfig/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import babel from '@rollup/plugin-babel';
import {terser} from 'rollup-plugin-terser';
import tsPlugin from '@rollup/plugin-typescript';

export default {
plugins: [babel({babelHelpers: 'bundled'}), terser()],
plugins: [babel({babelHelpers: 'bundled'}), terser(), tsPlugin()],
input: 'src/server/index.js',
output: [
{
Expand Down
2 changes: 1 addition & 1 deletion src/server/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export {default as getKindeServerSession} from '../session/index';
export {default as getKindeServerSession} from '../session/index.ts';
export {authMiddleware, withAuth} from '../authMiddleware/authMiddleware';
export {
LoginLink,
Expand Down
31 changes: 6 additions & 25 deletions src/session/getUser.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,18 @@
import {sessionManager} from './sessionManager';
import {kindeClient} from './kindeServerClient';
import {config} from '../config/index';
import {generateUserObject} from '../utils/generateUserObject';
import jwtDecode from 'jwt-decode';
import {NextApiRequest, NextApiResponse} from 'next';
import {KindeIdToken, KindeUser} from '../../types';
import jwtDecode from 'jwt-decode';
import {config} from '../config/index';
import {generateUserObject} from '../utils/generateUserObject';
import {sessionManager} from './sessionManager';

export const getUserFactory =
(req: NextApiRequest, res: NextApiResponse) =>
async <T = Record<string, any>>(): Promise<KindeUser<T>> => {
try {
const idToken = jwtDecode(
(await sessionManager(req, res).getSessionItem('id_token')) as string
) as KindeIdToken<T>;

return generateUserObject(idToken);

const user = await kindeClient.getUser(sessionManager(req, res));
const userProperties = await kindeClient.getClaimValue(
sessionManager(req, res),
'user_properties'
);
const phone_number = await kindeClient.getClaimValue(
sessionManager(req, res),
'phone_number',
'id_token'
);
const username = await kindeClient.getClaimValue(
sessionManager(req, res),
'preferred_username',
'id_token'
);
return generateUserObject(user, userProperties, phone_number, username);
) as KindeIdToken;
return generateUserObject(idToken) as KindeUser<T>;
} catch (error) {
if (config.isDebugMode) {
console.debug('getUser', error);
Expand Down
2 changes: 1 addition & 1 deletion src/session/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {getClaimFactory} from './getClaim';
import {config} from '../config/index';
import {NextApiRequest, NextApiResponse} from 'next';

export default function (req: NextApiRequest, res: NextApiResponse) {
export default function (req?: NextApiRequest, res?: NextApiResponse) {
return {
refreshTokens: async () => {
try {
Expand Down
89 changes: 18 additions & 71 deletions src/utils/generateUserObject.ts
Original file line number Diff line number Diff line change
@@ -1,72 +1,25 @@
import {
KindeAccessToken,
KindeIdToken,
KindeUser,
KindeUserProperties
} from '../../types';
import {KindeIdToken, KindeUser} from '../../types';

const getUserProperties = <T>(
properties: Record<string, {v: string}>
): KindeUserProperties<
T,
{
kp_usr_city: 'city';
kp_usr_industry: 'industry';
kp_usr_job_title: 'job_title';
kp_usr_middle_name: 'middle_name';
kp_usr_postcode: 'postcode';
kp_usr_salutation: 'salutation';
kp_usr_state_region: 'state_region';
kp_usr_street_address: 'street_address';
kp_usr_street_address_2: 'street_address_2';
}
> => {
const userProperties: KindeUserProperties<
T,
{
kp_usr_city: 'city';
kp_usr_industry: 'industry';
kp_usr_job_title: 'job_title';
kp_usr_middle_name: 'middle_name';
kp_usr_postcode: 'postcode';
kp_usr_salutation: 'salutation';
kp_usr_state_region: 'state_region';
kp_usr_street_address: 'street_address';
kp_usr_street_address_2: 'street_address_2';
}
> = Object.keys(properties).reduce((acc, key) => {
if (key.startsWith('kp_usr_')) {
acc[key.substring(7)] = properties[key]?.v;
}
acc[key] = properties[key]?.v;
return acc;
}, {});

return userProperties;
};

export const generateUserObject = (idToken: KindeIdToken): KindeUser => {
const user = {
type CustomPropertyType = Record<string, any>;
export const generateUserObject = (idToken: KindeIdToken) => {
const user: KindeUser<CustomPropertyType> = {
id: idToken.sub,
email: idToken.email,
family_name: idToken.family_name,
given_name: idToken.given_name,
name: idToken.name,
picture: idToken.picture,
username: idToken.preferred_username,
phone_number: idToken.phone_number
};
let res = user;

const properties = idToken.properties;
const properties = idToken.user_properties;

if (properties) {
}

let res = user;
if (userProperties) {
const {
kp_usr_city: cityObj,
kp_usr_industry: industryObj,
kp_usr_is_marketing_opt_in: isMarketingOptInObj,
kp_usr_job_title: jobTitleObj,
kp_usr_middle_name: middleNameObj,
kp_usr_postcode: postcodeObj,
Expand All @@ -75,18 +28,21 @@ export const generateUserObject = (idToken: KindeIdToken): KindeUser => {
kp_usr_street_address: streetAddressObj,
kp_usr_street_address_2: streetAddress2Obj,
...rest
} = userProperties;

const sanitizedRest = Object.keys(rest).reduce((acc, key) => {
acc[key] = rest[key]?.v;
return acc;
}, {});

} = properties;

const sanitizedRest: Record<string, any> = Object.keys(rest).reduce(
(acc, key) => {
acc[key] = rest[key]?.v;
return acc;
},
{}
);
res = {
...res,
...user,
properties: {
city: cityObj?.v,
industry: industryObj?.v,
is_marketing_opt_in: isMarketingOptInObj?.v,
job_title: jobTitleObj?.v,
middle_name: middleNameObj?.v,
postcode: postcodeObj?.v,
Expand All @@ -98,14 +54,5 @@ export const generateUserObject = (idToken: KindeIdToken): KindeUser => {
}
};
}

if (phone_number || username) {
res = {
...res,
...(phone_number && {phone_number}),
...(username && {username})
};
}

return res;
};
24 changes: 18 additions & 6 deletions types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,27 +103,39 @@ export type KindeIdToken = {
picture: string;
phone_number?: string;
preferred_username?: string;
properties?: KindeTokenUserProperties;
user_properties?: KindeTokenUserProperties;
rat: number;
sub: string;
updated_at: number;
};

type KindeUserProperties<T, Mapping extends Record<string, any>> = {
[K in keyof T as K extends keyof Mapping ? Mapping[K] : K]: T[K];
};
type KindeUserProperties<T = Record<string, any>> = {
city?: string;
industry?: string;
is_marketing_opt_in?: string;
job_title?: string;
middle_name?: string;
postcode?: string;
salutation?: string;
state_region?: string;
street_address?: string;
street_address_2?: string;
} & T;

export type KindeUser = {
export type KindeUserBase = {
id: string;
email: string | null;
given_name: string | null;
family_name: string | null;
picture: string | null;
username?: string | null;
phone_number?: string | null;
properties?: KindeUserProperties;
};

export interface KindeUser<T> extends KindeUserBase {
properties?: KindeUserProperties<T>;
}

export type KindePermissions = {
permissions: string[];
orgCode: string | null;
Expand Down

0 comments on commit 809fced

Please sign in to comment.