Skip to content

Commit

Permalink
Rename user to TokenUserPayload
Browse files Browse the repository at this point in the history
Currently the `jwt-passport`.`user` contains the user payload from jwt. This should not be confused to be the user but it's token data.

Change-type: major
Signed-off-by: Harald Fischer <[email protected]>
  • Loading branch information
fisehara committed Nov 16, 2023
1 parent db01abf commit 3a39ac6
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ import { apiRoot } from './balena';

export * as tags from './features/tags/validation';

export type { Creds, User } from './infra/auth/jwt-passport';
export type { Creds, TokenUserPayload } from './infra/auth/jwt-passport';
export type { Access } from './features/registry/registry';
export type { ApplicationType } from './features/application-types/application-types';
export type { DeviceTypeJson } from './features/device-types/device-type-json';
Expand Down
6 changes: 3 additions & 3 deletions src/infra/auth/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import _ from 'lodash';
import { sbvrUtils, hooks, permissions, errors } from '@balena/pinejs';

import { retrieveAPIKey } from './api-keys';
import { User } from './jwt-passport';
import { TokenUserPayload } from './jwt-passport';

import { getIP } from '../../lib/utils';
import type { PickDeferred, User as DbUser } from '../../balena-model';
Expand Down Expand Up @@ -190,12 +190,12 @@ export function getUser(
req: Request | hooks.HookReq,
txParam: Tx | undefined,
required?: true,
): Promise<User>;
): Promise<TokenUserPayload>;
export function getUser(
req: Request | hooks.HookReq,
txParam: Tx | undefined,
required: false,
): Promise<User | undefined>;
): Promise<TokenUserPayload | undefined>;
export async function getUser(
req: hooks.HookReq & Pick<Request, 'user' | 'creds'>,
/** You should always be passing a Tx, unless you are using this in a middleware. */
Expand Down
6 changes: 3 additions & 3 deletions src/infra/auth/jwt-passport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface ApiKey extends sbvrUtils.ApiKey {
key: string;
}

export interface User extends sbvrUtils.User {
export interface TokenUserPayload extends sbvrUtils.User {
username: string;
email: string | null;
created_at: string;
Expand All @@ -38,7 +38,7 @@ export interface User extends sbvrUtils.User {
authTime?: number;
}

export type Creds = ServiceToken | User | ScopedToken;
export type Creds = ServiceToken | TokenUserPayload | ScopedToken;
export type JwtUser = Creds | ScopedAccessToken;
const TOKEN_BODY_FIELD = '_token';

Expand Down Expand Up @@ -149,7 +149,7 @@ export const middleware: RequestHandler = (req, res, next) => {
twoFactorRequired: true;
};
} else {
req.user = auth as User & {
req.user = auth as TokenUserPayload & {
twoFactorRequired: false;
};
}
Expand Down
18 changes: 10 additions & 8 deletions src/infra/auth/jwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import jsonwebtoken from 'jsonwebtoken';

import { sbvrUtils, permissions, errors } from '@balena/pinejs';

import { SignOptions, User } from './jwt-passport';
import { SignOptions, TokenUserPayload } from './jwt-passport';

import { pseudoRandomBytesAsync } from '../../lib/utils';
import { getUser, userFields } from './auth';
Expand All @@ -21,7 +21,9 @@ const { api } = sbvrUtils;

const SUDO_TOKEN_VALIDITY = 20 * 60 * 1000;

export const checkSudoValidity = async (user: User): Promise<boolean> => {
export const checkSudoValidity = async (
user: TokenUserPayload,
): Promise<boolean> => {
const notAuthBefore = Date.now() - SUDO_TOKEN_VALIDITY;
return user.authTime != null && user.authTime > notAuthBefore;
};
Expand All @@ -36,14 +38,14 @@ export const generateNewJwtSecret = async (): Promise<string> => {
export const tokenFields = [...userFields];

export interface ExtraParams {
existingToken?: Partial<User>;
existingToken?: Partial<TokenUserPayload>;
jwtOptions?: SignOptions;
tx: Tx;
}

export type GetUserTokenDataFn = (
userId: number,
existingToken: Partial<User> | undefined,
existingToken: Partial<TokenUserPayload> | undefined,
tx: Tx,
) => PromiseLike<AnyObject>;

Expand All @@ -55,7 +57,7 @@ let $getUserTokenDataCallback: GetUserTokenDataFn = async (
userId,
existingToken,
tx: Tx,
): Promise<User> => {
): Promise<TokenUserPayload> => {
const [userData, permissionData] = await Promise.all([
api.resin.get({
resource: 'user',
Expand All @@ -70,20 +72,20 @@ let $getUserTokenDataCallback: GetUserTokenDataFn = async (
if (!userData || !permissionData) {
throw new Error('No data found?!');
}
const newTokenData: Partial<User> = _.pick(userData, tokenFields);
const newTokenData: Partial<TokenUserPayload> = _.pick(userData, tokenFields);

const tokenData = {
...existingToken,
...newTokenData,
permissions: permissionData,
} as User;
} as TokenUserPayload;

if (!Number.isFinite(tokenData.authTime!)) {
tokenData.authTime = Date.now();
}

// skip nullish attributes
return _.omitBy(tokenData, _.isNil) as User;
return _.omitBy(tokenData, _.isNil) as TokenUserPayload;
};

export const createSessionToken = async (
Expand Down
4 changes: 2 additions & 2 deletions test/test-lib/supertest.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { app } from '../../init';
import $supertest from 'supertest';
import { User } from '../../src/infra/auth/jwt-passport';
import { TokenUserPayload } from '../../src/infra/auth/jwt-passport';
import { ThisShouldNeverHappenError } from '../../src/infra/error-handling';

export type UserObjectParam = Partial<User & { token: string }>;
export type UserObjectParam = Partial<TokenUserPayload & { token: string }>;

export const augmentStatusAssertionError = () => {
const originalExpect: $supertest.Test['expect'] =
Expand Down
5 changes: 3 additions & 2 deletions typings/express-extension.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ declare namespace Express {
import type { Creds } from '../src/infra/auth/jwt-passport';
// For some reason TS doesn't like v so we had to use `import()`
// import type { User as ApiUser } from '../src/infra/auth/jwt-passport';
type ApiUser = import('../src/infra/auth/jwt-passport').User;
type TokenUserPayload =
import('../src/infra/auth/jwt-passport').TokenUserPayload;

// Augment Express.User to include the props of our ApiUser.
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface User extends ApiUser {}
interface User extends TokenUserPayload {}

export interface Request {
prefetchApiKey?: Resolvable<ApiKey>;
Expand Down

0 comments on commit 3a39ac6

Please sign in to comment.