Migrate token module to Server Preset (Part 2) (#4937)

This commit is contained in:
Eddy Nguyen 2024-06-13 23:17:56 +10:00 committed by GitHub
parent 6d0e0490fb
commit bf277aea72
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 203 additions and 170 deletions

1
.gitignore vendored
View file

@ -140,3 +140,4 @@ deployment/utils/vector.types.ts
deployment/utils/contour.types.ts
schema.graphql
resolvers.generated.ts

View file

@ -34,7 +34,6 @@ const config: CodegenConfig = {
'shared',
'support',
'target',
'token',
],
scalarsOverrides: {
DateTime: { type: 'string' },
@ -57,6 +56,11 @@ const config: CodegenConfig = {
SupportTicketPriority: '../shared/entities#SupportTicketPriority',
SupportTicketStatus: '../shared/entities#SupportTicketStatus',
},
resolversNonOptionalTypename: {
interfaceImplementingType: true,
unionMember: true,
excludeTypes: ['TokenInfoPayload'],
},
},
},
{

View file

@ -1,7 +1,7 @@
import { createModule } from 'graphql-modules';
import { TokenManager } from './providers/token-manager';
import { TokenStorage } from './providers/token-storage';
import { resolvers } from './resolvers';
import { resolvers } from './resolvers.generated';
import typeDefs from './module.graphql';
export const tokenModule = createModule({

View file

@ -1,161 +0,0 @@
import { z } from 'zod';
import { createConnection } from '../../shared/schema';
import { AuthManager } from '../auth/providers/auth-manager';
import { OrganizationManager } from '../organization/providers/organization-manager';
import { ProjectManager } from '../project/providers/project-manager';
import { IdTranslator } from '../shared/providers/id-translator';
import { TargetManager } from '../target/providers/target-manager';
import type { TokenModule } from './__generated__/types';
import { TokenManager } from './providers/token-manager';
const TokenNameModel = z.string().min(2).max(50);
export const resolvers: TokenModule.Resolvers = {
Query: {
async tokens(_, { selector }, { injector }) {
const translator = injector.get(IdTranslator);
const [organization, project, target] = await Promise.all([
translator.translateOrganizationId(selector),
translator.translateProjectId(selector),
translator.translateTargetId(selector),
]);
return injector.get(TokenManager).getTokens({
organization,
project,
target,
});
},
async tokenInfo(_, __, { injector }) {
try {
injector.get(AuthManager).ensureApiToken();
} catch (error) {
return {
__typename: 'TokenNotFoundError',
message: (error as Error).message,
};
}
return injector.get(TokenManager).getCurrentToken();
},
},
Mutation: {
async createToken(_, { input }, { injector }) {
const CreateTokenInputModel = z.object({
name: TokenNameModel,
});
const result = CreateTokenInputModel.safeParse(input);
if (!result.success) {
return {
error: {
message: result.error.formErrors.fieldErrors.name?.[0] ?? 'Please check your input.',
},
};
}
const translator = injector.get(IdTranslator);
const [organization, project, target] = await Promise.all([
translator.translateOrganizationId(input),
translator.translateProjectId(input),
translator.translateTargetId(input),
]);
const token = await injector.get(TokenManager).createToken({
name: input.name,
target,
project,
organization,
organizationScopes: input.organizationScopes,
projectScopes: input.projectScopes,
targetScopes: input.targetScopes,
});
return {
ok: {
selector: {
organization: input.organization,
project: input.project,
target: input.target,
},
createdToken: token,
secret: token.secret,
},
};
},
async deleteTokens(_, { input }, { injector }) {
const translator = injector.get(IdTranslator);
const [organization, project, target] = await Promise.all([
translator.translateOrganizationId(input),
translator.translateProjectId(input),
translator.translateTargetId(input),
]);
return {
selector: {
organization: input.organization,
project: input.project,
target: input.target,
},
deletedTokens: await injector.get(TokenManager).deleteTokens({
target,
project,
organization,
tokens: input.tokens,
}),
};
},
},
Token: {
id(token) {
return token.token;
},
alias(token) {
return token.tokenAlias;
},
},
TokenInfo: {
__isTypeOf(token) {
return 'token' in token;
},
token(token) {
return token;
},
organization(token, _, { injector }) {
return injector.get(OrganizationManager).getOrganization({
organization: token.organization,
});
},
project(token, _, { injector }) {
return injector.get(ProjectManager).getProject({
organization: token.organization,
project: token.project,
});
},
target(token, _, { injector }) {
return injector.get(TargetManager).getTarget({
organization: token.organization,
project: token.project,
target: token.target,
});
},
hasOrganizationScope(token, { scope }) {
return token.scopes.includes(scope);
},
hasProjectScope(token, { scope }) {
return token.scopes.includes(scope);
},
hasTargetScope(token, { scope }) {
return token.scopes.includes(scope);
},
},
Target: {
tokens(target, _, { injector }) {
return injector.get(TokenManager).getTokens({
target: target.id,
project: target.projectId,
organization: target.orgId,
});
},
},
TokenConnection: createConnection(),
};

View file

@ -0,0 +1,54 @@
import { z } from 'zod';
import { IdTranslator } from '../../../shared/providers/id-translator';
import { TokenManager } from '../../providers/token-manager';
import type { MutationResolvers } from './../../../../__generated__/types.next';
const TokenNameModel = z.string().min(2).max(50);
export const createToken: NonNullable<MutationResolvers['createToken']> = async (
_parent,
{ input },
{ injector },
) => {
const CreateTokenInputModel = z.object({
name: TokenNameModel,
});
const result = CreateTokenInputModel.safeParse(input);
if (!result.success) {
return {
error: {
message: result.error.formErrors.fieldErrors.name?.[0] ?? 'Please check your input.',
},
};
}
const translator = injector.get(IdTranslator);
const [organization, project, target] = await Promise.all([
translator.translateOrganizationId(input),
translator.translateProjectId(input),
translator.translateTargetId(input),
]);
const token = await injector.get(TokenManager).createToken({
name: input.name,
target,
project,
organization,
organizationScopes: input.organizationScopes,
projectScopes: input.projectScopes,
targetScopes: input.targetScopes,
});
return {
ok: {
selector: {
organization: input.organization,
project: input.project,
target: input.target,
},
createdToken: token,
secret: token.secret,
},
};
};

View file

@ -0,0 +1,29 @@
import { IdTranslator } from '../../../shared/providers/id-translator';
import { TokenManager } from '../../providers/token-manager';
import type { MutationResolvers } from './../../../../__generated__/types.next';
export const deleteTokens: NonNullable<MutationResolvers['deleteTokens']> = async (
_parent,
{ input },
{ injector },
) => {
const translator = injector.get(IdTranslator);
const [organization, project, target] = await Promise.all([
translator.translateOrganizationId(input),
translator.translateProjectId(input),
translator.translateTargetId(input),
]);
return {
selector: {
organization: input.organization,
project: input.project,
target: input.target,
},
deletedTokens: await injector.get(TokenManager).deleteTokens({
target,
project,
organization,
tokens: input.tokens,
}),
};
};

View file

@ -0,0 +1,20 @@
import { AuthManager } from '../../../auth/providers/auth-manager';
import { TokenManager } from '../../providers/token-manager';
import type { QueryResolvers } from './../../../../__generated__/types.next';
export const tokenInfo: NonNullable<QueryResolvers['tokenInfo']> = async (
_parent,
_arg,
{ injector },
) => {
try {
injector.get(AuthManager).ensureApiToken();
} catch (error) {
return {
__typename: 'TokenNotFoundError',
message: (error as Error).message,
};
}
return injector.get(TokenManager).getCurrentToken();
};

View file

@ -0,0 +1,22 @@
import { IdTranslator } from '../../../shared/providers/id-translator';
import { TokenManager } from '../../providers/token-manager';
import type { QueryResolvers } from './../../../../__generated__/types.next';
export const tokens: NonNullable<QueryResolvers['tokens']> = async (
_parent,
{ selector },
{ injector },
) => {
const translator = injector.get(IdTranslator);
const [organization, project, target] = await Promise.all([
translator.translateOrganizationId(selector),
translator.translateProjectId(selector),
translator.translateTargetId(selector),
]);
return injector.get(TokenManager).getTokens({
organization,
project,
target,
});
};

View file

@ -0,0 +1,12 @@
import { TokenManager } from '../providers/token-manager';
import type { TargetResolvers } from './../../../__generated__/types.next';
export const Target: Pick<TargetResolvers, 'tokens'> = {
tokens(target, _, { injector }) {
return injector.get(TokenManager).getTokens({
target: target.id,
project: target.projectId,
organization: target.orgId,
});
},
};

View file

@ -0,0 +1,10 @@
import type { TokenResolvers } from './../../../__generated__/types.next';
export const Token: TokenResolvers = {
id(token) {
return token.token;
},
alias(token) {
return token.tokenAlias;
},
};

View file

@ -0,0 +1,9 @@
import { createConnection } from '../../../shared/schema';
import type { ResolversTypes, TokenConnectionResolvers } from './../../../__generated__/types.next';
const connection = createConnection<ResolversTypes['Token']>();
export const TokenConnection: TokenConnectionResolvers = {
nodes: connection.nodes,
total: connection.total,
};

View file

@ -0,0 +1,40 @@
import { OrganizationManager } from '../../organization/providers/organization-manager';
import { ProjectManager } from '../../project/providers/project-manager';
import { TargetManager } from '../../target/providers/target-manager';
import type { TokenInfoResolvers } from './../../../__generated__/types.next';
export const TokenInfo: TokenInfoResolvers = {
__isTypeOf(token) {
return 'token' in token;
},
token(token) {
return token;
},
organization(token, _, { injector }) {
return injector.get(OrganizationManager).getOrganization({
organization: token.organization,
});
},
project(token, _, { injector }) {
return injector.get(ProjectManager).getProject({
organization: token.organization,
project: token.project,
});
},
target(token, _, { injector }) {
return injector.get(TargetManager).getTarget({
organization: token.organization,
project: token.project,
target: token.target,
});
},
hasOrganizationScope(token, { scope }) {
return token.scopes.includes(scope);
},
hasProjectScope(token, { scope }) {
return token.scopes.includes(scope);
},
hasTargetScope(token, { scope }) {
return token.scopes.includes(scope);
},
};

View file

@ -1,7 +0,0 @@
/* This file was automatically generated. DO NOT UPDATE MANUALLY. */
import type { Resolvers } from './../../__generated__/types.next';
import { usageEstimation as Query_usageEstimation } from './resolvers/Query/usageEstimation';
export const resolvers: Resolvers = {
Query: { usageEstimation: Query_usageEstimation },
};