@fphgov/authentication-sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +38 -0
- package/protos/authentication.proto +15 -0
- package/src/client.ts +47 -0
- package/src/index.ts +3 -0
- package/src/interceptor.ts +27 -0
- package/src/types.ts +17 -0
package/package.json
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fphgov/authentication-sdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Authentication gRPC service SDK only for FPH",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"default": "./dist/index.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist/",
|
|
15
|
+
"protos/",
|
|
16
|
+
"src/"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc -p tsconfig.build.json",
|
|
20
|
+
"build:watch": "tsc -p tsconfig.build.json --watch"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@grpc/grpc-js": "^1.14.4",
|
|
24
|
+
"@grpc/proto-loader": "^0.8.0"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"@nestjs/common": ">=11.0.0",
|
|
28
|
+
"@nestjs/microservices": ">=11.0.0",
|
|
29
|
+
"rxjs": ">=7.0.0"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@nestjs/common": "^11.0.0",
|
|
33
|
+
"@nestjs/microservices": "^11.0.0",
|
|
34
|
+
"@types/node": "^24.0.0",
|
|
35
|
+
"rxjs": "^7.8.0",
|
|
36
|
+
"typescript": "^5.9.0"
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src/client.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as grpc from '@grpc/grpc-js'
|
|
2
|
+
import * as protoLoader from '@grpc/proto-loader'
|
|
3
|
+
import * as path from 'path'
|
|
4
|
+
import { type AuthServiceClient, type AuthServiceConstructor } from './types'
|
|
5
|
+
|
|
6
|
+
const { status } = grpc
|
|
7
|
+
|
|
8
|
+
const PROTO_PATH = path.join(__dirname, '../protos/authentication.proto')
|
|
9
|
+
|
|
10
|
+
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
|
|
11
|
+
keepCase: true,
|
|
12
|
+
defaults: true,
|
|
13
|
+
enums: String,
|
|
14
|
+
oneofs: true,
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
const proto = grpc.loadPackageDefinition(packageDefinition) as unknown as {
|
|
18
|
+
authentication: { AuthService: AuthServiceConstructor }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class AuthenticationClient {
|
|
22
|
+
private readonly grpcClient: AuthServiceClient
|
|
23
|
+
|
|
24
|
+
constructor(url: string) {
|
|
25
|
+
this.grpcClient = new proto.authentication.AuthService(url, grpc.credentials.createInsecure())
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
authenticate(token: string): Promise<boolean> {
|
|
29
|
+
return new Promise((resolve, reject) => {
|
|
30
|
+
this.grpcClient.authenticate({ token }, (err, response) => {
|
|
31
|
+
if (err) {
|
|
32
|
+
if (err.code === status.UNAUTHENTICATED) {
|
|
33
|
+
resolve(false)
|
|
34
|
+
} else {
|
|
35
|
+
reject(err)
|
|
36
|
+
}
|
|
37
|
+
} else {
|
|
38
|
+
resolve(response.success)
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
close(): void {
|
|
45
|
+
this.grpcClient.close()
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ExecutionContext, type CallHandler } from '@nestjs/common'
|
|
2
|
+
import { RpcException } from '@nestjs/microservices'
|
|
3
|
+
import { type Observable } from 'rxjs'
|
|
4
|
+
import { Metadata, status } from '@grpc/grpc-js'
|
|
5
|
+
import { AuthenticationClient } from './client'
|
|
6
|
+
|
|
7
|
+
export class AuthenticationInterceptor {
|
|
8
|
+
constructor(private readonly client: AuthenticationClient) {}
|
|
9
|
+
|
|
10
|
+
async intercept(context: ExecutionContext, next: CallHandler): Promise<Observable<unknown>> {
|
|
11
|
+
const metadata = context.getArgByIndex<Metadata>(1)
|
|
12
|
+
const authValues = metadata?.get('authorization')
|
|
13
|
+
const token = authValues?.[0] as string | undefined
|
|
14
|
+
|
|
15
|
+
if (!token) {
|
|
16
|
+
throw new RpcException({ code: status.UNAUTHENTICATED, message: 'Missing authentication token' })
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const success = await this.client.authenticate(token)
|
|
20
|
+
|
|
21
|
+
if (!success) {
|
|
22
|
+
throw new RpcException({ code: status.UNAUTHENTICATED, message: 'Invalid authentication token' })
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return next.handle()
|
|
26
|
+
}
|
|
27
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import * as grpc from '@grpc/grpc-js'
|
|
2
|
+
|
|
3
|
+
export interface AuthRequest {
|
|
4
|
+
token: string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export interface AuthResponse {
|
|
8
|
+
success: boolean
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface AuthServiceClient extends grpc.Client {
|
|
12
|
+
authenticate(req: AuthRequest, cb: (err: grpc.ServiceError | null, res: AuthResponse) => void): void
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface AuthServiceConstructor {
|
|
16
|
+
new (url: string, credentials: grpc.ChannelCredentials): AuthServiceClient
|
|
17
|
+
}
|