diff --git a/dictation_client/codegen.sh b/dictation_client/codegen.sh
new file mode 100644
index 0000000..5d09ae3
--- /dev/null
+++ b/dictation_client/codegen.sh
@@ -0,0 +1,2 @@
+npx openapi-generator-cli version-manager set latest
+npx openapi-generator-cli generate -g typescript-axios -i /app/dictation_server/src/api/odms/openapi.json -o /app/dictation_client/src/api/
diff --git a/dictation_client/openapitools.json b/dictation_client/openapitools.json
index c871d87..0436938 100644
--- a/dictation_client/openapitools.json
+++ b/dictation_client/openapitools.json
@@ -2,6 +2,6 @@
"$schema": "./node_modules/@openapitools/openapi-generator-cli/config.schema.json",
"spaces": 2,
"generator-cli": {
- "version": "6.2.1"
+ "version": "6.4.0"
}
}
diff --git a/dictation_client/src/pages/SamplePage/index.tsx b/dictation_client/src/pages/SamplePage/index.tsx
index b588b41..0721e10 100644
--- a/dictation_client/src/pages/SamplePage/index.tsx
+++ b/dictation_client/src/pages/SamplePage/index.tsx
@@ -1,7 +1,11 @@
import React from "react";
-const SamplePage: React.FC = () => {
- return (
hello whorld!
Dictation App Service Site
)
-};
+const SamplePage: React.FC = () => (
+
+ hello whorld!
+
+ Dictation App Service Site
+
+);
export default SamplePage;
diff --git a/dictation_server/src/api/generate.ts b/dictation_server/src/api/generate.ts
index 3ab6410..676000c 100644
--- a/dictation_server/src/api/generate.ts
+++ b/dictation_server/src/api/generate.ts
@@ -21,6 +21,12 @@ async function bootstrap(): Promise {
const options = new DocumentBuilder()
.setTitle('ODMSOpenAPI')
.setVersion('1.0.0')
+ .addBearerAuth({
+ type: 'http',
+ scheme: 'bearer',
+ bearerFormat: 'JWT',
+ in: 'header',
+ })
.build();
const document = SwaggerModule.createDocument(app, options);
await fs.writeFile(
diff --git a/dictation_server/src/api/odms/openapi.json b/dictation_server/src/api/odms/openapi.json
index d5c8e55..ce787bb 100644
--- a/dictation_server/src/api/odms/openapi.json
+++ b/dictation_server/src/api/odms/openapi.json
@@ -12,10 +12,109 @@
}
}
}
+ },
+ "/auth/token": {
+ "post": {
+ "operationId": "token",
+ "summary": "",
+ "parameters": [],
+ "requestBody": {
+ "required": true,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/TokenRequest"
+ }
+ }
+ }
+ },
+ "responses": {
+ "200": {
+ "description": "成功時のレスポンス",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/TokenResponse"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "認証エラー",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "想定外のサーバーエラー",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "auth"
+ ]
+ }
+ },
+ "/auth/accessToken": {
+ "post": {
+ "operationId": "accessToken",
+ "summary": "",
+ "parameters": [],
+ "responses": {
+ "200": {
+ "description": "成功時のレスポンス",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/AccessTokenResponse"
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "認証エラー",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "想定外のサーバーエラー",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ErrorResponse"
+ }
+ }
+ }
+ }
+ },
+ "tags": [
+ "auth"
+ ],
+ "security": [
+ {
+ "bearer": []
+ }
+ ]
+ }
}
},
"info": {
- "title": "OMDSOpenAPI",
+ "title": "ODMSOpenAPI",
"description": "",
"version": "1.0.0",
"contact": {}
@@ -23,6 +122,72 @@
"tags": [],
"servers": [],
"components": {
- "schemas": {}
+ "securitySchemes": {
+ "bearer": {
+ "scheme": "bearer",
+ "bearerFormat": "JWT",
+ "type": "http",
+ "in": "header"
+ }
+ },
+ "schemas": {
+ "TokenRequest": {
+ "type": "object",
+ "properties": {
+ "idToken": {
+ "type": "string"
+ },
+ "type": {
+ "type": "string",
+ "description": "web or mobile or desktop"
+ }
+ },
+ "required": [
+ "idToken",
+ "type"
+ ]
+ },
+ "TokenResponse": {
+ "type": "object",
+ "properties": {
+ "refreshToken": {
+ "type": "string"
+ },
+ "accessToken": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "refreshToken",
+ "accessToken"
+ ]
+ },
+ "ErrorResponse": {
+ "type": "object",
+ "properties": {
+ "message": {
+ "type": "string"
+ },
+ "code": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "message",
+ "code"
+ ]
+ },
+ "AccessTokenResponse": {
+ "type": "object",
+ "properties": {
+ "accessToken": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "accessToken"
+ ]
+ }
+ }
}
}
\ No newline at end of file
diff --git a/dictation_server/src/app.module.ts b/dictation_server/src/app.module.ts
index 4fea7f6..0106524 100644
--- a/dictation_server/src/app.module.ts
+++ b/dictation_server/src/app.module.ts
@@ -1,11 +1,11 @@
import { MiddlewareConsumer, Module } from '@nestjs/common';
import { HealthController } from './health.controller';
import { ServeStaticModule } from '@nestjs/serve-static';
-import { ConfigModule, ConfigService } from '@nestjs/config';
+import { ConfigModule } from '@nestjs/config';
import { join } from 'path';
-import { TypeOrmModule } from '@nestjs/typeorm';
import { LoggerMiddleware } from './common/loggerMiddleware';
import { AuthModule } from './features/auth/auth.module';
+import { AuthController } from './features/auth/auth.controller';
@Module({
imports: [
@@ -32,7 +32,7 @@ import { AuthModule } from './features/auth/auth.module';
// inject: [ConfigService],
// }),
],
- controllers: [HealthController],
+ controllers: [HealthController, AuthController],
providers: [],
})
export class AppModule {
diff --git a/dictation_server/src/common/error/code.ts b/dictation_server/src/common/error/code.ts
new file mode 100644
index 0000000..75bd4d4
--- /dev/null
+++ b/dictation_server/src/common/error/code.ts
@@ -0,0 +1,4 @@
+//TODO 仮のエラーコード作成
+export const ErrorCodes = [
+ 'E009999', // 汎用エラー
+] as const;
diff --git a/dictation_server/src/common/error/makeErrorResponse.ts b/dictation_server/src/common/error/makeErrorResponse.ts
new file mode 100644
index 0000000..0a677b4
--- /dev/null
+++ b/dictation_server/src/common/error/makeErrorResponse.ts
@@ -0,0 +1,10 @@
+import { errors } from './message';
+import { ErrorCodeType, ErrorResponse } from './types/types';
+
+export const makeErrorResponse = (errorcode: ErrorCodeType): ErrorResponse => {
+ const msg = errors[errorcode];
+ return {
+ code: errorcode,
+ message: msg,
+ };
+};
diff --git a/dictation_server/src/common/error/message.ts b/dictation_server/src/common/error/message.ts
new file mode 100644
index 0000000..e2cbc14
--- /dev/null
+++ b/dictation_server/src/common/error/message.ts
@@ -0,0 +1,6 @@
+import { Errors } from './types/types';
+
+// エラーコードとメッセージ対応表
+export const errors: Errors = {
+ E009999: 'Internal Server Error',
+};
diff --git a/dictation_server/src/common/error/types/types.ts b/dictation_server/src/common/error/types/types.ts
new file mode 100644
index 0000000..8746924
--- /dev/null
+++ b/dictation_server/src/common/error/types/types.ts
@@ -0,0 +1,15 @@
+import { ApiProperty } from '@nestjs/swagger';
+import { ErrorCodes } from '../code';
+
+export class ErrorResponse {
+ @ApiProperty()
+ message: string;
+ @ApiProperty()
+ code: string;
+}
+
+export type ErrorCodeType = (typeof ErrorCodes)[number];
+
+export type Errors = {
+ [P in ErrorCodeType]: string;
+};
diff --git a/dictation_server/src/features/auth/auth.controller.ts b/dictation_server/src/features/auth/auth.controller.ts
index 268eeb2..bbc1f5a 100644
--- a/dictation_server/src/features/auth/auth.controller.ts
+++ b/dictation_server/src/features/auth/auth.controller.ts
@@ -1,4 +1,66 @@
-import { Controller } from '@nestjs/common';
-
+import { Body, Controller, Headers, HttpStatus, Post } from '@nestjs/common';
+import {
+ ApiResponse,
+ ApiOperation,
+ ApiBearerAuth,
+ ApiTags,
+} from '@nestjs/swagger';
+import { ErrorResponse } from '../../common/error/types/types';
+import {
+ AccessTokenResponse,
+ TokenRequest,
+ TokenResponse,
+} from './types/types';
+@ApiTags('auth')
@Controller('auth')
-export class AuthController {}
+export class AuthController {
+ @Post('token')
+ @ApiResponse({
+ status: HttpStatus.OK,
+ type: TokenResponse,
+ description: '成功時のレスポンス',
+ })
+ @ApiResponse({
+ status: HttpStatus.UNAUTHORIZED,
+ description: '認証エラー',
+ type: ErrorResponse,
+ })
+ @ApiResponse({
+ status: HttpStatus.INTERNAL_SERVER_ERROR,
+ description: '想定外のサーバーエラー',
+ type: ErrorResponse,
+ })
+ @ApiOperation({ operationId: 'token' })
+ async token(@Body() body: TokenRequest): Promise {
+ console.log(body);
+
+ return {
+ accessToken: '',
+ refreshToken: '',
+ };
+ }
+
+ @Post('accessToken')
+ @ApiBearerAuth()
+ @ApiResponse({
+ status: HttpStatus.OK,
+ type: AccessTokenResponse,
+ description: '成功時のレスポンス',
+ })
+ @ApiResponse({
+ status: HttpStatus.UNAUTHORIZED,
+ description: '認証エラー',
+ type: ErrorResponse,
+ })
+ @ApiResponse({
+ status: HttpStatus.INTERNAL_SERVER_ERROR,
+ description: '想定外のサーバーエラー',
+ type: ErrorResponse,
+ })
+ @ApiOperation({ operationId: 'accessToken' })
+ async accessToken(@Headers() headers): Promise {
+ console.log(headers['authorization']);
+
+ return { accessToken: '' };
+ }
+}
diff --git a/dictation_server/src/features/auth/types/types.ts b/dictation_server/src/features/auth/types/types.ts
new file mode 100644
index 0000000..95f41a3
--- /dev/null
+++ b/dictation_server/src/features/auth/types/types.ts
@@ -0,0 +1,19 @@
+import { ApiProperty } from '@nestjs/swagger';
+
+export class TokenRequest {
+ @ApiProperty()
+ idToken: string;
+ @ApiProperty({ description: 'web or mobile or desktop' })
+ type: string;
+}
+export class TokenResponse {
+ @ApiProperty()
+ refreshToken: string;
+ @ApiProperty()
+ accessToken: string;
+}
+export class AccessTokenResponse {
+ @ApiProperty()
+ accessToken: string;
+}
+export class AccessTokenRequest {}
diff --git a/dictation_server/src/main.ts b/dictation_server/src/main.ts
index 9a2faeb..c9e3be2 100644
--- a/dictation_server/src/main.ts
+++ b/dictation_server/src/main.ts
@@ -18,6 +18,12 @@ async function bootstrap() {
const options = new DocumentBuilder()
.setTitle('ODMSOpenAPI')
.setVersion('1.0.0')
+ .addBearerAuth({
+ type: 'http',
+ scheme: 'bearer',
+ bearerFormat: 'JWT',
+ in: 'header',
+ })
.build();
const document = SwaggerModule.createDocument(app, options);
SwaggerModule.setup('api', app, document);