Skip to content

Commit

Permalink
Add new auth concept
Browse files Browse the repository at this point in the history
  • Loading branch information
jhoncool committed Jan 20, 2025
1 parent 17eb3c1 commit 381aaa3
Show file tree
Hide file tree
Showing 24 changed files with 430 additions and 63 deletions.
2 changes: 2 additions & 0 deletions api/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ export {default as axiosInstance} from '../src/utils/axios';
export {objectKeys} from '../src/utils/utility-types';

export {whereBuilderInterTenantGetEntries} from '../src/db/models/navigation/utils';

export {getEnvCert, getEnvVariable, getEnvTokenVariable, isTrueArg} from '../src/utils/env-utils';
162 changes: 156 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"crc-32": "1.2.0",
"db-errors": "^0.2.3",
"dotenv": "^8.2.0",
"jsonwebtoken": "^9.0.2",
"knex": "^3.1.0",
"lodash": "^4.17.21",
"minimist": "^1.2.5",
Expand All @@ -41,8 +42,9 @@
"@trendyol/jest-testcontainers": "^2.1.1",
"@types/express": "^4.17.15",
"@types/jest": "^29.5.12",
"@types/jsonwebtoken": "^9.0.7",
"@types/lodash": "^4.17.4",
"@types/node": "^18.14.4",
"@types/node": "^20.17.12",
"@types/pg": "^7.14.11",
"@types/supertest": "^2.0.10",
"@types/swagger-ui-express": "^4.1.7",
Expand Down
5 changes: 3 additions & 2 deletions scripts/setup-dev-env.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const appPath = path.join(__dirname, '..');
const templateFilePath = path.join(appPath, `dev/env/${templateName}`);

let templateContent = readFileSync(templateFilePath).toString();
const secretsSection = `${SECRETS_SECTION_START}\n${templateContent}\n${SECRETS_SECTION_END}`;

if (envName === 'development') {
try {
Expand All @@ -29,6 +28,8 @@ if (envName === 'development') {
}
}

const templateSection = `${SECRETS_SECTION_START}\n${templateContent}\n${SECRETS_SECTION_END}`;

let currentEnv;

try {
Expand All @@ -39,4 +40,4 @@ try {
currentEnv = `${SECRETS_SECTION_START}\n${SECRETS_SECTION_END}`;
}

writeFileSync(path.join(appPath, '.env'), currentEnv.replace(REPLACE_REGEXP, secretsSection));
writeFileSync(path.join(appPath, '.env'), currentEnv.replace(REPLACE_REGEXP, templateSection));
2 changes: 1 addition & 1 deletion src/components/api-docs/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const getAdditionalHeaders = (
config.appAuthPolicy === AuthPolicy.disabled ||
routeDescription.authPolicy === AuthPolicy.disabled;

if (!authDisabled && config.zitadelEnabled) {
if (!authDisabled && (config.zitadelEnabled || config.isAuthEnabled)) {
headers.push(
z.strictObject({
[AUTHORIZATION_HEADER]: z.string(),
Expand Down
5 changes: 5 additions & 0 deletions src/components/auth/constants/error-constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// use `US.AUTH.<name>` prefix for most cases

export const AUTH_ERRORS = {
UNAUTHORIZED_ACCESS: 'US.AUTH.UNAUTHORIZED_ACCESS',
};
7 changes: 7 additions & 0 deletions src/components/auth/constants/role.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export enum UserRole {
Editor = 'datalens.editor',
Admin = 'datalens.admin',
Viewer = 'datalens.viewer',
Visitor = 'datalens.visitor',
Creator = 'datalens.creator',
}
52 changes: 52 additions & 0 deletions src/components/auth/middlewares/app-auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {NextFunction, Request, Response} from '@gravity-ui/expresskit';
import jwt, {type Algorithm} from 'jsonwebtoken';

import {AUTHORIZATION_HEADER, DL_AUTH_HEADER_KEY} from '../../../const/common';
import {AUTH_ERRORS} from '../constants/error-constants';
import type {AccessTokenPayload} from '../types/token';

const ALGORITHMS: Algorithm[] = ['RS256'];

export const appAuth = async (req: Request, res: Response, next: NextFunction) => {
req.ctx.log('AUTH');

const authorization = req.headers[AUTHORIZATION_HEADER];

if (authorization) {
const accessToken = authorization.slice(DL_AUTH_HEADER_KEY.length + 1);

if (accessToken) {
try {
req.ctx.log('CHECK_ACCESS_TOKEN');

const {userId, sessionId, roles} = jwt.verify(
accessToken,
req.ctx.config.authTokenPublicKey || '',
{
algorithms: ALGORITHMS,
},
) as AccessTokenPayload;

req.originalContext.set('user', {
userId,
sessionId,
accessToken,
roles,
});

// for ctx info
res.locals.userId = userId;
res.locals.login = userId;

req.ctx.log('CHECK_ACCESS_TOKEN_SUCCESS');

next();
return;
} catch (err) {
req.ctx.logError('CHECK_ACCESS_TOKEN_ERROR', err);
}
}
}

res.status(401).send({code: AUTH_ERRORS.UNAUTHORIZED_ACCESS, message: 'Unauthorized access'});
};
12 changes: 12 additions & 0 deletions src/components/auth/types/token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type {UserRole} from '../constants/role';

export interface ExpirableTokenPayload {
iat: number;
exp: number;
}

export interface AccessTokenPayload extends ExpirableTokenPayload {
userId: string;
sessionId: string;
roles: `${UserRole}`[];
}
8 changes: 8 additions & 0 deletions src/components/auth/types/user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type {UserRole} from '../constants/role';

export interface CtxUser {
userId: string;
sessionId: string;
accessToken: string;
roles: `${UserRole}`[];
}
Loading

0 comments on commit 381aaa3

Please sign in to comment.