feat: replace websocket connection validation with grpc (#954)
* feat: replace websocket connection validation with grpc * fix(api-gateway): error logs metadata details * fix binding * fix logs severity on websockets * add user uuid to grpc call error logs
This commit is contained in:
parent
4600a49e88
commit
d5c1b76de0
15 changed files with 658 additions and 51 deletions
|
@ -91,9 +91,12 @@ void container.load().then((container) => {
|
|||
|
||||
server.setErrorConfig((app) => {
|
||||
app.use((error: Record<string, unknown>, request: Request, response: Response, _next: NextFunction) => {
|
||||
logger.error(
|
||||
`[URL: |${request.method}| ${request.url}][SNJS: ${request.headers['x-snjs-version']}][Application: ${request.headers['x-application-version']}] Error thrown: ${error.stack}`,
|
||||
)
|
||||
logger.error(`${error.stack}`, {
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
snjs: request.headers['x-snjs-version'],
|
||||
application: request.headers['x-application-version'],
|
||||
})
|
||||
logger.debug(
|
||||
`[URL: |${request.method}| ${request.url}][SNJS: ${request.headers['x-snjs-version']}][Application: ${
|
||||
request.headers['x-application-version']
|
||||
|
|
|
@ -22,19 +22,13 @@ import { EndpointResolver } from '../Service/Resolver/EndpointResolver'
|
|||
import { RequiredCrossServiceTokenMiddleware } from '../Controller/RequiredCrossServiceTokenMiddleware'
|
||||
import { OptionalCrossServiceTokenMiddleware } from '../Controller/OptionalCrossServiceTokenMiddleware'
|
||||
import { Transform } from 'stream'
|
||||
import {
|
||||
ISessionsClient,
|
||||
ISyncingClient,
|
||||
SessionsClient,
|
||||
SyncRequest,
|
||||
SyncResponse,
|
||||
SyncingClient,
|
||||
} from '@standardnotes/grpc'
|
||||
import { AuthClient, IAuthClient, ISyncingClient, SyncRequest, SyncResponse, SyncingClient } from '@standardnotes/grpc'
|
||||
import { GRPCServiceProxy } from '../Service/gRPC/GRPCServiceProxy'
|
||||
import { GRPCSyncingServerServiceProxy } from '../Service/gRPC/GRPCSyncingServerServiceProxy'
|
||||
import { SyncResponseHttpRepresentation } from '../Mapping/Sync/Http/SyncResponseHttpRepresentation'
|
||||
import { SyncRequestGRPCMapper } from '../Mapping/Sync/GRPC/SyncRequestGRPCMapper'
|
||||
import { SyncResponseGRPCMapper } from '../Mapping/Sync/GRPC/SyncResponseGRPCMapper'
|
||||
import { GRPCWebSocketAuthMiddleware } from '../Controller/GRPCWebSocketAuthMiddleware'
|
||||
|
||||
export class ContainerConfigLoader {
|
||||
async load(configuration?: {
|
||||
|
@ -51,6 +45,7 @@ export class ContainerConfigLoader {
|
|||
const isConfiguredForSelfHosting = env.get('MODE', true) === 'self-hosted'
|
||||
const isConfiguredForHomeServerOrSelfHosting = isConfiguredForHomeServer || isConfiguredForSelfHosting
|
||||
const isConfiguredForInMemoryCache = env.get('CACHE_TYPE', true) === 'memory'
|
||||
const isConfiguredForGRPCProxy = env.get('SERVICE_PROXY_TYPE', true) === 'grpc'
|
||||
|
||||
container
|
||||
.bind<boolean>(TYPES.ApiGateway_IS_CONFIGURED_FOR_HOME_SERVER_OR_SELF_HOSTING)
|
||||
|
@ -122,7 +117,6 @@ export class ContainerConfigLoader {
|
|||
container
|
||||
.bind<OptionalCrossServiceTokenMiddleware>(TYPES.ApiGateway_OptionalCrossServiceTokenMiddleware)
|
||||
.to(OptionalCrossServiceTokenMiddleware)
|
||||
container.bind<WebSocketAuthMiddleware>(TYPES.ApiGateway_WebSocketAuthMiddleware).to(WebSocketAuthMiddleware)
|
||||
container
|
||||
.bind<SubscriptionTokenAuthMiddleware>(TYPES.ApiGateway_SubscriptionTokenAuthMiddleware)
|
||||
.to(SubscriptionTokenAuthMiddleware)
|
||||
|
@ -153,7 +147,6 @@ export class ContainerConfigLoader {
|
|||
new DirectCallServiceProxy(configuration.serviceContainer, container.get(TYPES.ApiGateway_FILES_SERVER_URL)),
|
||||
)
|
||||
} else {
|
||||
const isConfiguredForGRPCProxy = env.get('SERVICE_PROXY_TYPE', true) === 'grpc'
|
||||
if (isConfiguredForGRPCProxy) {
|
||||
container.bind(TYPES.ApiGateway_AUTH_SERVER_GRPC_URL).toConstantValue(env.get('AUTH_SERVER_GRPC_URL'))
|
||||
container.bind(TYPES.ApiGateway_SYNCING_SERVER_GRPC_URL).toConstantValue(env.get('SYNCING_SERVER_GRPC_URL'))
|
||||
|
@ -165,8 +158,8 @@ export class ContainerConfigLoader {
|
|||
? +env.get('GRPC_MAX_MESSAGE_SIZE', true)
|
||||
: 1024 * 1024 * 50
|
||||
|
||||
container.bind<ISessionsClient>(TYPES.ApiGateway_GRPCSessionsClient).toConstantValue(
|
||||
new SessionsClient(
|
||||
container.bind<IAuthClient>(TYPES.ApiGateway_GRPCAuthClient).toConstantValue(
|
||||
new AuthClient(
|
||||
container.get<string>(TYPES.ApiGateway_AUTH_SERVER_GRPC_URL),
|
||||
grpc.credentials.createInsecure(),
|
||||
{
|
||||
|
@ -229,7 +222,7 @@ export class ContainerConfigLoader {
|
|||
container.get<CrossServiceTokenCacheInterface>(TYPES.ApiGateway_CrossServiceTokenCache),
|
||||
container.get<winston.Logger>(TYPES.ApiGateway_Logger),
|
||||
container.get<TimerInterface>(TYPES.ApiGateway_Timer),
|
||||
container.get<ISessionsClient>(TYPES.ApiGateway_GRPCSessionsClient),
|
||||
container.get<IAuthClient>(TYPES.ApiGateway_GRPCAuthClient),
|
||||
container.get<GRPCSyncingServerServiceProxy>(TYPES.ApiGateway_GRPCSyncingServerServiceProxy),
|
||||
),
|
||||
)
|
||||
|
@ -238,6 +231,20 @@ export class ContainerConfigLoader {
|
|||
}
|
||||
}
|
||||
|
||||
if (isConfiguredForGRPCProxy) {
|
||||
container
|
||||
.bind<GRPCWebSocketAuthMiddleware>(TYPES.ApiGateway_WebSocketAuthMiddleware)
|
||||
.toConstantValue(
|
||||
new GRPCWebSocketAuthMiddleware(
|
||||
container.get<IAuthClient>(TYPES.ApiGateway_GRPCAuthClient),
|
||||
container.get<string>(TYPES.ApiGateway_AUTH_JWT_SECRET),
|
||||
container.get<winston.Logger>(TYPES.ApiGateway_Logger),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
container.bind<WebSocketAuthMiddleware>(TYPES.ApiGateway_WebSocketAuthMiddleware).to(WebSocketAuthMiddleware)
|
||||
}
|
||||
|
||||
logger.debug('Configuration complete')
|
||||
|
||||
return container
|
||||
|
|
|
@ -34,6 +34,6 @@ export const TYPES = {
|
|||
ApiGateway_CrossServiceTokenCache: Symbol.for('ApiGateway_CrossServiceTokenCache'),
|
||||
ApiGateway_Timer: Symbol.for('ApiGateway_Timer'),
|
||||
ApiGateway_EndpointResolver: Symbol.for('ApiGateway_EndpointResolver'),
|
||||
ApiGateway_GRPCSessionsClient: Symbol.for('ApiGateway_GRPCSessionsClient'),
|
||||
ApiGateway_GRPCAuthClient: Symbol.for('ApiGateway_GRPCAuthClient'),
|
||||
ApiGateway_GRPCSyncingClient: Symbol.for('ApiGateway_GRPCSyncingClient'),
|
||||
}
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
import { CrossServiceTokenData } from '@standardnotes/security'
|
||||
import * as grpc from '@grpc/grpc-js'
|
||||
import { NextFunction, Request, Response } from 'express'
|
||||
import { BaseMiddleware } from 'inversify-express-utils'
|
||||
import { verify } from 'jsonwebtoken'
|
||||
import { Logger } from 'winston'
|
||||
import { ConnectionValidationResponse, IAuthClient, WebsocketConnectionAuthorizationHeader } from '@standardnotes/grpc'
|
||||
|
||||
export class GRPCWebSocketAuthMiddleware extends BaseMiddleware {
|
||||
constructor(
|
||||
private authClient: IAuthClient,
|
||||
private jwtSecret: string,
|
||||
private logger: Logger,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
|
||||
async handler(request: Request, response: Response, next: NextFunction): Promise<void> {
|
||||
const authHeaderValue = request.headers.authorization as string
|
||||
|
||||
if (!authHeaderValue) {
|
||||
response.status(401).send({
|
||||
error: {
|
||||
tag: 'invalid-auth',
|
||||
message: 'Invalid login credentials.',
|
||||
},
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const promise = new Promise((resolve, reject) => {
|
||||
try {
|
||||
const request = new WebsocketConnectionAuthorizationHeader()
|
||||
request.setToken(authHeaderValue)
|
||||
|
||||
this.authClient.validateWebsocket(
|
||||
request,
|
||||
(error: grpc.ServiceError | null, response: ConnectionValidationResponse) => {
|
||||
if (error) {
|
||||
const responseCode = error.metadata.get('x-auth-error-response-code').pop()
|
||||
if (responseCode) {
|
||||
return resolve({
|
||||
status: +responseCode,
|
||||
data: {
|
||||
error: {
|
||||
message: error.metadata.get('x-auth-error-message').pop(),
|
||||
tag: error.metadata.get('x-auth-error-tag').pop(),
|
||||
},
|
||||
},
|
||||
headers: {
|
||||
contentType: 'application/json',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
return reject(error)
|
||||
}
|
||||
|
||||
return resolve({
|
||||
status: 200,
|
||||
data: {
|
||||
authToken: response.getCrossServiceToken(),
|
||||
},
|
||||
headers: {
|
||||
contentType: 'application/json',
|
||||
},
|
||||
})
|
||||
},
|
||||
)
|
||||
} catch (error) {
|
||||
return reject(error)
|
||||
}
|
||||
})
|
||||
|
||||
try {
|
||||
const authResponse = (await promise) as {
|
||||
status: number
|
||||
headers: Record<string, unknown>
|
||||
data: Record<string, unknown>
|
||||
}
|
||||
|
||||
if (authResponse.status > 200) {
|
||||
response.setHeader('content-type', authResponse.headers['content-type'] as string)
|
||||
response.status(authResponse.status).send(authResponse.data)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
const crossServiceToken = authResponse.data.authToken as string
|
||||
|
||||
response.locals.authToken = crossServiceToken
|
||||
|
||||
const decodedToken = <CrossServiceTokenData>verify(crossServiceToken, this.jwtSecret, { algorithms: ['HS256'] })
|
||||
|
||||
response.locals.user = decodedToken.user
|
||||
response.locals.session = decodedToken.session
|
||||
response.locals.roles = decodedToken.roles
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Could not pass the request to websocket connection validation on underlying service: ${
|
||||
(error as Error).message
|
||||
}`,
|
||||
)
|
||||
|
||||
response
|
||||
.status(500)
|
||||
.send(
|
||||
"Unfortunately, we couldn't handle your request. Please try again or contact our support if the error persists.",
|
||||
)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ import { AxiosInstance, AxiosError, AxiosResponse, Method } from 'axios'
|
|||
import { Request, Response } from 'express'
|
||||
import { Logger } from 'winston'
|
||||
import { TimerInterface } from '@standardnotes/time'
|
||||
import { ISessionsClient, AuthorizationHeader, SessionValidationResponse } from '@standardnotes/grpc'
|
||||
import { IAuthClient, AuthorizationHeader, SessionValidationResponse } from '@standardnotes/grpc'
|
||||
import * as grpc from '@grpc/grpc-js'
|
||||
|
||||
import { CrossServiceTokenCacheInterface } from '../Cache/CrossServiceTokenCacheInterface'
|
||||
|
@ -23,7 +23,7 @@ export class GRPCServiceProxy implements ServiceProxyInterface {
|
|||
private crossServiceTokenCache: CrossServiceTokenCacheInterface,
|
||||
private logger: Logger,
|
||||
private timer: TimerInterface,
|
||||
private sessionsClient: ISessionsClient,
|
||||
private authClient: IAuthClient,
|
||||
private gRPCSyncingServerServiceProxy: GRPCSyncingServerServiceProxy,
|
||||
) {}
|
||||
|
||||
|
@ -41,7 +41,7 @@ export class GRPCServiceProxy implements ServiceProxyInterface {
|
|||
|
||||
this.logger.debug('[GRPCServiceProxy] Validating session via gRPC')
|
||||
|
||||
this.sessionsClient.validate(
|
||||
this.authClient.validate(
|
||||
request,
|
||||
metadata,
|
||||
(error: grpc.ServiceError | null, response: SessionValidationResponse) => {
|
||||
|
|
|
@ -44,9 +44,9 @@ export class GRPCSyncingServerServiceProxy {
|
|||
|
||||
if (error.code === Status.INTERNAL) {
|
||||
this.logger.error(
|
||||
`[GRPCSyncingServerServiceProxy] Internal gRPC error: ${error.message}. Payload: ${JSON.stringify(
|
||||
payload,
|
||||
)}`,
|
||||
`[GRPCSyncingServerServiceProxy][${response.locals.user.uuid}] Internal gRPC error: ${
|
||||
error.message
|
||||
}. Payload: ${JSON.stringify(payload)}`,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -61,9 +61,9 @@ export class GRPCSyncingServerServiceProxy {
|
|||
(error as Record<string, unknown>).code === Status.INTERNAL
|
||||
) {
|
||||
this.logger.error(
|
||||
`[GRPCSyncingServerServiceProxy] Internal gRPC error: ${JSON.stringify(error)}. Payload: ${JSON.stringify(
|
||||
payload,
|
||||
)}`,
|
||||
`[GRPCSyncingServerServiceProxy][${response.locals.user.uuid}] Internal gRPC error: ${JSON.stringify(
|
||||
error,
|
||||
)}. Payload: ${JSON.stringify(payload)}`,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,11 @@ import { InversifyExpressServer } from 'inversify-express-utils'
|
|||
import { ContainerConfigLoader } from '../src/Bootstrap/Container'
|
||||
import TYPES from '../src/Bootstrap/Types'
|
||||
import { Env } from '../src/Bootstrap/Env'
|
||||
import { SessionsServer } from '../src/Infra/gRPC/SessionsServer'
|
||||
import { SessionsService } from '@standardnotes/grpc'
|
||||
import { AuthServer } from '../src/Infra/gRPC/AuthServer'
|
||||
import { AuthService } from '@standardnotes/grpc'
|
||||
import { AuthenticateRequest } from '../src/Domain/UseCase/AuthenticateRequest'
|
||||
import { CreateCrossServiceToken } from '../src/Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken'
|
||||
import { TokenDecoderInterface, WebSocketConnectionTokenData } from '@standardnotes/security'
|
||||
|
||||
const container = new ContainerConfigLoader()
|
||||
void container.load().then((container) => {
|
||||
|
@ -95,14 +96,16 @@ void container.load().then((container) => {
|
|||
|
||||
const gRPCPort = env.get('GRPC_PORT', true) ? +env.get('GRPC_PORT', true) : 50051
|
||||
|
||||
const sessionsServer = new SessionsServer(
|
||||
const authServer = new AuthServer(
|
||||
container.get<AuthenticateRequest>(TYPES.Auth_AuthenticateRequest),
|
||||
container.get<CreateCrossServiceToken>(TYPES.Auth_CreateCrossServiceToken),
|
||||
container.get<TokenDecoderInterface<WebSocketConnectionTokenData>>(TYPES.Auth_WebSocketConnectionTokenDecoder),
|
||||
container.get<winston.Logger>(TYPES.Auth_Logger),
|
||||
)
|
||||
|
||||
grpcServer.addService(SessionsService, {
|
||||
validate: sessionsServer.validate.bind(sessionsServer),
|
||||
grpcServer.addService(AuthService, {
|
||||
validate: authServer.validate.bind(authServer),
|
||||
validateWebsocket: authServer.validateWebsocket.bind(authServer),
|
||||
})
|
||||
grpcServer.bindAsync(`0.0.0.0:${gRPCPort}`, grpc.ServerCredentials.createInsecure(), (error, port) => {
|
||||
if (error) {
|
||||
|
|
|
@ -1,20 +1,92 @@
|
|||
import * as grpc from '@grpc/grpc-js'
|
||||
import { Status } from '@grpc/grpc-js/build/src/constants'
|
||||
|
||||
import { AuthorizationHeader, ISessionsServer, SessionValidationResponse } from '@standardnotes/grpc'
|
||||
import {
|
||||
AuthorizationHeader,
|
||||
ConnectionValidationResponse,
|
||||
IAuthServer,
|
||||
SessionValidationResponse,
|
||||
WebsocketConnectionAuthorizationHeader,
|
||||
} from '@standardnotes/grpc'
|
||||
|
||||
import { AuthenticateRequest } from '../../Domain/UseCase/AuthenticateRequest'
|
||||
import { User } from '../../Domain/User/User'
|
||||
import { CreateCrossServiceToken } from '../../Domain/UseCase/CreateCrossServiceToken/CreateCrossServiceToken'
|
||||
import { Logger } from 'winston'
|
||||
import { ErrorTag } from '@standardnotes/responses'
|
||||
import { TokenDecoderInterface, WebSocketConnectionTokenData } from '@standardnotes/security'
|
||||
|
||||
export class SessionsServer implements ISessionsServer {
|
||||
export class AuthServer implements IAuthServer {
|
||||
constructor(
|
||||
private authenticateRequest: AuthenticateRequest,
|
||||
private createCrossServiceToken: CreateCrossServiceToken,
|
||||
protected tokenDecoder: TokenDecoderInterface<WebSocketConnectionTokenData>,
|
||||
private logger: Logger,
|
||||
) {}
|
||||
|
||||
async validateWebsocket(
|
||||
call: grpc.ServerUnaryCall<WebsocketConnectionAuthorizationHeader, ConnectionValidationResponse>,
|
||||
callback: grpc.sendUnaryData<ConnectionValidationResponse>,
|
||||
): Promise<void> {
|
||||
try {
|
||||
const token: WebSocketConnectionTokenData | undefined = this.tokenDecoder.decodeToken(call.request.getToken())
|
||||
|
||||
if (token === undefined) {
|
||||
const metadata = new grpc.Metadata()
|
||||
metadata.set('x-auth-error-message', 'Invalid authorization token.')
|
||||
metadata.set('x-auth-error-tag', ErrorTag.AuthInvalid)
|
||||
metadata.set('x-auth-error-response-code', '401')
|
||||
return callback(
|
||||
{
|
||||
code: Status.PERMISSION_DENIED,
|
||||
message: 'Invalid authorization token.',
|
||||
name: ErrorTag.AuthInvalid,
|
||||
metadata,
|
||||
},
|
||||
null,
|
||||
)
|
||||
}
|
||||
|
||||
const resultOrError = await this.createCrossServiceToken.execute({
|
||||
userUuid: token.userUuid,
|
||||
sessionUuid: token.sessionUuid,
|
||||
})
|
||||
if (resultOrError.isFailed()) {
|
||||
const metadata = new grpc.Metadata()
|
||||
metadata.set('x-auth-error-message', resultOrError.getError())
|
||||
metadata.set('x-auth-error-response-code', '400')
|
||||
|
||||
return callback(
|
||||
{
|
||||
code: Status.INVALID_ARGUMENT,
|
||||
message: resultOrError.getError(),
|
||||
name: 'INVALID_ARGUMENT',
|
||||
metadata,
|
||||
},
|
||||
null,
|
||||
)
|
||||
}
|
||||
|
||||
const response = new ConnectionValidationResponse()
|
||||
response.setCrossServiceToken(resultOrError.getValue())
|
||||
|
||||
this.logger.debug('[SessionsServer] Websocket connection validated via gRPC')
|
||||
|
||||
callback(null, response)
|
||||
} catch (error) {
|
||||
this.logger.error(`[SessionsServer] Error validating websocket connection via gRPC: ${(error as Error).message}`)
|
||||
|
||||
callback(
|
||||
{
|
||||
code: Status.UNKNOWN,
|
||||
message: 'An error occurred while validating websocket connection',
|
||||
name: 'UNKNOWN',
|
||||
},
|
||||
null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async validate(
|
||||
call: grpc.ServerUnaryCall<AuthorizationHeader, SessionValidationResponse>,
|
||||
callback: grpc.sendUnaryData<SessionValidationResponse>,
|
39
packages/grpc/lib/auth_grpc_pb.d.ts
vendored
39
packages/grpc/lib/auth_grpc_pb.d.ts
vendored
|
@ -7,12 +7,13 @@
|
|||
import * as grpc from "@grpc/grpc-js";
|
||||
import * as auth_pb from "./auth_pb";
|
||||
|
||||
interface ISessionsService extends grpc.ServiceDefinition<grpc.UntypedServiceImplementation> {
|
||||
validate: ISessionsService_Ivalidate;
|
||||
interface IAuthService extends grpc.ServiceDefinition<grpc.UntypedServiceImplementation> {
|
||||
validate: IAuthService_Ivalidate;
|
||||
validateWebsocket: IAuthService_IvalidateWebsocket;
|
||||
}
|
||||
|
||||
interface ISessionsService_Ivalidate extends grpc.MethodDefinition<auth_pb.AuthorizationHeader, auth_pb.SessionValidationResponse> {
|
||||
path: "/auth.Sessions/validate";
|
||||
interface IAuthService_Ivalidate extends grpc.MethodDefinition<auth_pb.AuthorizationHeader, auth_pb.SessionValidationResponse> {
|
||||
path: "/auth.Auth/validate";
|
||||
requestStream: false;
|
||||
responseStream: false;
|
||||
requestSerialize: grpc.serialize<auth_pb.AuthorizationHeader>;
|
||||
|
@ -20,22 +21,38 @@ interface ISessionsService_Ivalidate extends grpc.MethodDefinition<auth_pb.Autho
|
|||
responseSerialize: grpc.serialize<auth_pb.SessionValidationResponse>;
|
||||
responseDeserialize: grpc.deserialize<auth_pb.SessionValidationResponse>;
|
||||
}
|
||||
|
||||
export const SessionsService: ISessionsService;
|
||||
|
||||
export interface ISessionsServer {
|
||||
validate: grpc.handleUnaryCall<auth_pb.AuthorizationHeader, auth_pb.SessionValidationResponse>;
|
||||
interface IAuthService_IvalidateWebsocket extends grpc.MethodDefinition<auth_pb.WebsocketConnectionAuthorizationHeader, auth_pb.ConnectionValidationResponse> {
|
||||
path: "/auth.Auth/validateWebsocket";
|
||||
requestStream: false;
|
||||
responseStream: false;
|
||||
requestSerialize: grpc.serialize<auth_pb.WebsocketConnectionAuthorizationHeader>;
|
||||
requestDeserialize: grpc.deserialize<auth_pb.WebsocketConnectionAuthorizationHeader>;
|
||||
responseSerialize: grpc.serialize<auth_pb.ConnectionValidationResponse>;
|
||||
responseDeserialize: grpc.deserialize<auth_pb.ConnectionValidationResponse>;
|
||||
}
|
||||
|
||||
export interface ISessionsClient {
|
||||
export const AuthService: IAuthService;
|
||||
|
||||
export interface IAuthServer {
|
||||
validate: grpc.handleUnaryCall<auth_pb.AuthorizationHeader, auth_pb.SessionValidationResponse>;
|
||||
validateWebsocket: grpc.handleUnaryCall<auth_pb.WebsocketConnectionAuthorizationHeader, auth_pb.ConnectionValidationResponse>;
|
||||
}
|
||||
|
||||
export interface IAuthClient {
|
||||
validate(request: auth_pb.AuthorizationHeader, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
validate(request: auth_pb.AuthorizationHeader, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
validate(request: auth_pb.AuthorizationHeader, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
}
|
||||
|
||||
export class SessionsClient extends grpc.Client implements ISessionsClient {
|
||||
export class AuthClient extends grpc.Client implements IAuthClient {
|
||||
constructor(address: string, credentials: grpc.ChannelCredentials, options?: object);
|
||||
public validate(request: auth_pb.AuthorizationHeader, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
public validate(request: auth_pb.AuthorizationHeader, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
public validate(request: auth_pb.AuthorizationHeader, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: auth_pb.SessionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
public validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
public validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
public validateWebsocket(request: auth_pb.WebsocketConnectionAuthorizationHeader, metadata: grpc.Metadata, options: Partial<grpc.CallOptions>, callback: (error: grpc.ServiceError | null, response: auth_pb.ConnectionValidationResponse) => void): grpc.ClientUnaryCall;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,17 @@ function deserialize_auth_AuthorizationHeader(buffer_arg) {
|
|||
return auth_pb.AuthorizationHeader.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_auth_ConnectionValidationResponse(arg) {
|
||||
if (!(arg instanceof auth_pb.ConnectionValidationResponse)) {
|
||||
throw new Error('Expected argument of type auth.ConnectionValidationResponse');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
function deserialize_auth_ConnectionValidationResponse(buffer_arg) {
|
||||
return auth_pb.ConnectionValidationResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_auth_SessionValidationResponse(arg) {
|
||||
if (!(arg instanceof auth_pb.SessionValidationResponse)) {
|
||||
throw new Error('Expected argument of type auth.SessionValidationResponse');
|
||||
|
@ -26,10 +37,21 @@ function deserialize_auth_SessionValidationResponse(buffer_arg) {
|
|||
return auth_pb.SessionValidationResponse.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
function serialize_auth_WebsocketConnectionAuthorizationHeader(arg) {
|
||||
if (!(arg instanceof auth_pb.WebsocketConnectionAuthorizationHeader)) {
|
||||
throw new Error('Expected argument of type auth.WebsocketConnectionAuthorizationHeader');
|
||||
}
|
||||
return Buffer.from(arg.serializeBinary());
|
||||
}
|
||||
|
||||
var SessionsService = exports.SessionsService = {
|
||||
function deserialize_auth_WebsocketConnectionAuthorizationHeader(buffer_arg) {
|
||||
return auth_pb.WebsocketConnectionAuthorizationHeader.deserializeBinary(new Uint8Array(buffer_arg));
|
||||
}
|
||||
|
||||
|
||||
var AuthService = exports.AuthService = {
|
||||
validate: {
|
||||
path: '/auth.Sessions/validate',
|
||||
path: '/auth.Auth/validate',
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestType: auth_pb.AuthorizationHeader,
|
||||
|
@ -39,6 +61,17 @@ var SessionsService = exports.SessionsService = {
|
|||
responseSerialize: serialize_auth_SessionValidationResponse,
|
||||
responseDeserialize: deserialize_auth_SessionValidationResponse,
|
||||
},
|
||||
validateWebsocket: {
|
||||
path: '/auth.Auth/validateWebsocket',
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestType: auth_pb.WebsocketConnectionAuthorizationHeader,
|
||||
responseType: auth_pb.ConnectionValidationResponse,
|
||||
requestSerialize: serialize_auth_WebsocketConnectionAuthorizationHeader,
|
||||
requestDeserialize: deserialize_auth_WebsocketConnectionAuthorizationHeader,
|
||||
responseSerialize: serialize_auth_ConnectionValidationResponse,
|
||||
responseDeserialize: deserialize_auth_ConnectionValidationResponse,
|
||||
},
|
||||
};
|
||||
|
||||
exports.SessionsClient = grpc.makeGenericClientConstructor(SessionsService);
|
||||
exports.AuthClient = grpc.makeGenericClientConstructor(AuthService);
|
||||
|
|
40
packages/grpc/lib/auth_pb.d.ts
vendored
40
packages/grpc/lib/auth_pb.d.ts
vendored
|
@ -45,3 +45,43 @@ export namespace SessionValidationResponse {
|
|||
crossServiceToken: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class WebsocketConnectionAuthorizationHeader extends jspb.Message {
|
||||
getToken(): string;
|
||||
setToken(value: string): WebsocketConnectionAuthorizationHeader;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): WebsocketConnectionAuthorizationHeader.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: WebsocketConnectionAuthorizationHeader): WebsocketConnectionAuthorizationHeader.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: WebsocketConnectionAuthorizationHeader, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): WebsocketConnectionAuthorizationHeader;
|
||||
static deserializeBinaryFromReader(message: WebsocketConnectionAuthorizationHeader, reader: jspb.BinaryReader): WebsocketConnectionAuthorizationHeader;
|
||||
}
|
||||
|
||||
export namespace WebsocketConnectionAuthorizationHeader {
|
||||
export type AsObject = {
|
||||
token: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class ConnectionValidationResponse extends jspb.Message {
|
||||
getCrossServiceToken(): string;
|
||||
setCrossServiceToken(value: string): ConnectionValidationResponse;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ConnectionValidationResponse.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ConnectionValidationResponse): ConnectionValidationResponse.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: ConnectionValidationResponse, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): ConnectionValidationResponse;
|
||||
static deserializeBinaryFromReader(message: ConnectionValidationResponse, reader: jspb.BinaryReader): ConnectionValidationResponse;
|
||||
}
|
||||
|
||||
export namespace ConnectionValidationResponse {
|
||||
export type AsObject = {
|
||||
crossServiceToken: string,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,9 @@ var global = (function() {
|
|||
}.call(null));
|
||||
|
||||
goog.exportSymbol('proto.auth.AuthorizationHeader', null, global);
|
||||
goog.exportSymbol('proto.auth.ConnectionValidationResponse', null, global);
|
||||
goog.exportSymbol('proto.auth.SessionValidationResponse', null, global);
|
||||
goog.exportSymbol('proto.auth.WebsocketConnectionAuthorizationHeader', null, global);
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
|
@ -65,6 +67,48 @@ if (goog.DEBUG && !COMPILED) {
|
|||
*/
|
||||
proto.auth.SessionValidationResponse.displayName = 'proto.auth.SessionValidationResponse';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.auth.WebsocketConnectionAuthorizationHeader, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader.displayName = 'proto.auth.WebsocketConnectionAuthorizationHeader';
|
||||
}
|
||||
/**
|
||||
* Generated by JsPbCodeGenerator.
|
||||
* @param {Array=} opt_data Optional initial data array, typically from a
|
||||
* server response, or constructed directly in Javascript. The array is used
|
||||
* in place and becomes part of the constructed object. It is not cloned.
|
||||
* If no data is provided, the constructed object will be empty, but still
|
||||
* valid.
|
||||
* @extends {jspb.Message}
|
||||
* @constructor
|
||||
*/
|
||||
proto.auth.ConnectionValidationResponse = function(opt_data) {
|
||||
jspb.Message.initialize(this, opt_data, 0, -1, null, null);
|
||||
};
|
||||
goog.inherits(proto.auth.ConnectionValidationResponse, jspb.Message);
|
||||
if (goog.DEBUG && !COMPILED) {
|
||||
/**
|
||||
* @public
|
||||
* @override
|
||||
*/
|
||||
proto.auth.ConnectionValidationResponse.displayName = 'proto.auth.ConnectionValidationResponse';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -325,4 +369,264 @@ proto.auth.SessionValidationResponse.prototype.setCrossServiceToken = function(v
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.auth.WebsocketConnectionAuthorizationHeader.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.auth.WebsocketConnectionAuthorizationHeader} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
token: jspb.Message.getFieldWithDefault(msg, 1, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.auth.WebsocketConnectionAuthorizationHeader}
|
||||
*/
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.auth.WebsocketConnectionAuthorizationHeader;
|
||||
return proto.auth.WebsocketConnectionAuthorizationHeader.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.auth.WebsocketConnectionAuthorizationHeader} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.auth.WebsocketConnectionAuthorizationHeader}
|
||||
*/
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setToken(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.auth.WebsocketConnectionAuthorizationHeader} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getToken();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string token = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader.prototype.getToken = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.auth.WebsocketConnectionAuthorizationHeader} returns this
|
||||
*/
|
||||
proto.auth.WebsocketConnectionAuthorizationHeader.prototype.setToken = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (jspb.Message.GENERATE_TO_OBJECT) {
|
||||
/**
|
||||
* Creates an object representation of this proto.
|
||||
* Field names that are reserved in JavaScript and will be renamed to pb_name.
|
||||
* Optional fields that are not set will be set to undefined.
|
||||
* To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
|
||||
* For the list of reserved names please see:
|
||||
* net/proto2/compiler/js/internal/generator.cc#kKeyword.
|
||||
* @param {boolean=} opt_includeInstance Deprecated. whether to include the
|
||||
* JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @return {!Object}
|
||||
*/
|
||||
proto.auth.ConnectionValidationResponse.prototype.toObject = function(opt_includeInstance) {
|
||||
return proto.auth.ConnectionValidationResponse.toObject(opt_includeInstance, this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Static version of the {@see toObject} method.
|
||||
* @param {boolean|undefined} includeInstance Deprecated. Whether to include
|
||||
* the JSPB instance for transitional soy proto support:
|
||||
* http://goto/soy-param-migration
|
||||
* @param {!proto.auth.ConnectionValidationResponse} msg The msg instance to transform.
|
||||
* @return {!Object}
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.auth.ConnectionValidationResponse.toObject = function(includeInstance, msg) {
|
||||
var f, obj = {
|
||||
crossServiceToken: jspb.Message.getFieldWithDefault(msg, 1, "")
|
||||
};
|
||||
|
||||
if (includeInstance) {
|
||||
obj.$jspbMessageInstance = msg;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format).
|
||||
* @param {jspb.ByteSource} bytes The bytes to deserialize.
|
||||
* @return {!proto.auth.ConnectionValidationResponse}
|
||||
*/
|
||||
proto.auth.ConnectionValidationResponse.deserializeBinary = function(bytes) {
|
||||
var reader = new jspb.BinaryReader(bytes);
|
||||
var msg = new proto.auth.ConnectionValidationResponse;
|
||||
return proto.auth.ConnectionValidationResponse.deserializeBinaryFromReader(msg, reader);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deserializes binary data (in protobuf wire format) from the
|
||||
* given reader into the given message object.
|
||||
* @param {!proto.auth.ConnectionValidationResponse} msg The message object to deserialize into.
|
||||
* @param {!jspb.BinaryReader} reader The BinaryReader to use.
|
||||
* @return {!proto.auth.ConnectionValidationResponse}
|
||||
*/
|
||||
proto.auth.ConnectionValidationResponse.deserializeBinaryFromReader = function(msg, reader) {
|
||||
while (reader.nextField()) {
|
||||
if (reader.isEndGroup()) {
|
||||
break;
|
||||
}
|
||||
var field = reader.getFieldNumber();
|
||||
switch (field) {
|
||||
case 1:
|
||||
var value = /** @type {string} */ (reader.readString());
|
||||
msg.setCrossServiceToken(value);
|
||||
break;
|
||||
default:
|
||||
reader.skipField();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return msg;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the message to binary data (in protobuf wire format).
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
proto.auth.ConnectionValidationResponse.prototype.serializeBinary = function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
proto.auth.ConnectionValidationResponse.serializeBinaryToWriter(this, writer);
|
||||
return writer.getResultBuffer();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Serializes the given message to binary data (in protobuf wire
|
||||
* format), writing to the given BinaryWriter.
|
||||
* @param {!proto.auth.ConnectionValidationResponse} message
|
||||
* @param {!jspb.BinaryWriter} writer
|
||||
* @suppress {unusedLocalVariables} f is only used for nested messages
|
||||
*/
|
||||
proto.auth.ConnectionValidationResponse.serializeBinaryToWriter = function(message, writer) {
|
||||
var f = undefined;
|
||||
f = message.getCrossServiceToken();
|
||||
if (f.length > 0) {
|
||||
writer.writeString(
|
||||
1,
|
||||
f
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* optional string cross_service_token = 1;
|
||||
* @return {string}
|
||||
*/
|
||||
proto.auth.ConnectionValidationResponse.prototype.getCrossServiceToken = function() {
|
||||
return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} value
|
||||
* @return {!proto.auth.ConnectionValidationResponse} returns this
|
||||
*/
|
||||
proto.auth.ConnectionValidationResponse.prototype.setCrossServiceToken = function(value) {
|
||||
return jspb.Message.setProto3StringField(this, 1, value);
|
||||
};
|
||||
|
||||
|
||||
goog.object.extend(exports, proto.auth);
|
||||
|
|
|
@ -10,6 +10,15 @@ message SessionValidationResponse {
|
|||
string cross_service_token = 1;
|
||||
}
|
||||
|
||||
service Sessions {
|
||||
rpc validate(AuthorizationHeader) returns (SessionValidationResponse) {}
|
||||
message WebsocketConnectionAuthorizationHeader {
|
||||
string token = 1;
|
||||
}
|
||||
|
||||
message ConnectionValidationResponse {
|
||||
string cross_service_token = 1;
|
||||
}
|
||||
|
||||
service Auth {
|
||||
rpc validate(AuthorizationHeader) returns (SessionValidationResponse) {}
|
||||
rpc validateWebsocket(WebsocketConnectionAuthorizationHeader) returns (ConnectionValidationResponse) {}
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ describe('SendMessageToClient', () => {
|
|||
message: 'message',
|
||||
})
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.isFailed()).toBe(false)
|
||||
expect(webSocketsConnectionRepository.removeConnection).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -49,9 +49,11 @@ export class SendMessageToClient implements UseCaseInterface<void> {
|
|||
}
|
||||
} catch (error) {
|
||||
if (error instanceof GoneException) {
|
||||
this.logger.info(`Connection ${connection.props.connectionId} for user ${userUuid.value} is gone. Removing.`)
|
||||
this.logger.debug(`Connection ${connection.props.connectionId} for user ${userUuid.value} is gone. Removing.`)
|
||||
|
||||
await this.removeGoneConnection(connection.props.connectionId)
|
||||
|
||||
return Result.ok()
|
||||
}
|
||||
|
||||
return Result.fail(
|
||||
|
|
Loading…
Reference in a new issue