{
  "swagger": "2.0",
  "info": {
    "title": "pool",
    "version": "1.0"
  },
  "host": "localhost:8509",
  "schemes": [
    "https"
  ],
  "produces": [
    "application/json"
  ],
  "consumes": [
    "application/json"
  ],
  "tags": [
    {
      "name": "token",
      "description": "Oauth2のトークン"
    },
    {
      "name": "email-verifications",
      "description": "メール認証"
    },
    {
      "name": "phone-number-verifications",
      "description": "電話番号認証"
    },
    {
      "name": "users",
      "description": "ユーザ"
    }
  ],
  "paths": {
    "/oauth2/token": {
      "post": {
        "summary": "トークン発行",
        "tags": [
          "token"
        ],
        "operationId": "issueToken",
        "security": [],
        "consumes": [
          "application/x-www-form-urlencoded"
        ],
        "parameters": [
          {
            "name": "grant_type",
            "in": "formData",
            "type": "string",
            "enum": [
              "Bearer"
            ],
            "required": true
          },
          {
            "name": "username",
            "in": "formData",
            "type": "string",
            "required": true
          },
          {
            "name": "password",
            "in": "formData",
            "type": "string",
            "required": true
          },
          {
            "name": "mfa_id",
            "in": "formData",
            "type": "string"
          }
        ],
        "responses": {
          "201": {
            "description": "Accepted",
            "schema": {
              "$ref": "#/definitions/OAuth2Token"
            }
          }
        }
      }
    },
    "/email-verifications/{id}/check": {
      "get": {
        "summary": "メール認証でのコード照合を行う",
        "description": "アプリのAPIクライアントではなく、メーラーが起動したブラウザが開くエンドポイント。認証メール内にリンクとして埋め込まれている。",
        "operationId": "checkEmailVerification",
        "tags": [
          "email-verifications"
        ],
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "メール認証のid",
            "required": true,
            "type": "string"
          },
          {
            "name": "code",
            "in": "query",
            "description": "認証メール内に埋め込まれた認証用コード",
            "required": true,
            "type": "string"
          },
          {
            "name": "redirect_url",
            "in": "query",
            "description": "認証成功時にリダイレクトする先のURL",
            "required": true,
            "type": "string",
            "pattern": "https?://[\\w!?/\\+\\-_~=;\\.,*&@#$%\\(\\)\\'\\[\\]]+"
          }
        ],
        "responses": {
          "302": {
            "description": "照合成功時",
            "headers": {
              "Location": {
                "type": "string",
                "description": "照合成功時の遷移先"
              }
            }
          },
          "307": {
            "description": "照合失敗時",
            "headers": {
              "Location": {
                "type": "string",
                "description": "照合失敗時の遷移先"
              }
            }
          }
        }
      }
    },
    "/phone-number-verifications": {
      "post": {
        "summary": "電話番号認証を要求する",
        "operationId": "createPhoneNumberVerification",
        "tags": [
          "phone-number-verifications"
        ],
        "security": [],
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/CreatePhoneNumberVerificationBody"
            }
          }
        ],
        "responses": {
          "201": {
            "$ref": "#/responses/PhoneNumberVerification"
          }
        }
      }
    },
    "/phone-number-verifications/{id}/check": {
      "post": {
        "summary": "電話番号認証でのコード照合を行う",
        "operationId": "checkPhoneNumberVerification",
        "tags": [
          "phone-number-verifications"
        ],
        "security": [],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "description": "電話番号認証のid",
            "required": true,
            "type": "string"
          },
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/CheckPhoneNumberVerificationBody"
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/responses/PhoneNumberVerification"
          }
        }
      }
    },
    "/signup": {
      "post": {
        "summary": "新規会員登録",
        "tags": [
          "users"
        ],
        "operationId": "signup",
        "security": [],
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/SingupBody"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "OK",
            "schema": {
              "type": "object",
              "properties": {
                "token": {
                  "$ref": "#/definitions/Token"
                }
              }
            }
          }
        }
      }
    },
    "/users/me": {
      "get": {
        "summary": "自分のユーザ情報を取得する",
        "operationId": "showMe",
        "tags": [
          "users"
        ],
        "responses": {
          "200": {
            "$ref": "#/responses/User"
          }
        }
      }
    },
    "/users/me/email": {
      "put": {
        "summary": "自分のメールアドレスを変更する",
        "operationId": "changeMyEmail",
        "tags": [
          "users"
        ],
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/ChangeMyEmailBody"
            }
          }
        ],
        "responses": {
          "202": {
            "$ref": "#/responses/User"
          }
        }
      }
    },
    "/users/me/phone-number": {
      "put": {
        "summary": "自分の電話番号を変更する",
        "operationId": "changeMyPhoneNumber",
        "tags": [
          "users"
        ],
        "parameters": [
          {
            "name": "body",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/ChangeMyPhoneNumberBody"
            }
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/responses/User"
          }
        }
      }
    }
  },
  "responses": {
    "User": {
      "description": "ユーザ",
      "schema": {
        "$ref": "#/definitions/User"
      }
    },
    "EmailVerification": {
      "description": "メール認証",
      "schema": {
        "$ref": "#/definitions/EmailVerification"
      }
    },
    "PhoneNumberVerification": {
      "description": "電話番号認証",
      "schema": {
        "$ref": "#/definitions/PhoneNumberVerification"
      }
    }
  },
  "definitions": {
    "User": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer"
        },
        "email": {
          "type": "string"
        },
        "phoneNumber": {
          "$ref": "#/definitions/PhoneNumber"
        }
      }
    },
    "OAuth2Token": {
      "type": "object",
      "description": "OAuth2の仕様に合わせるため、これのみスネークケースになっている。Tokenと同じ情報を持つ。",
      "properties": {
        "access_token": {
          "type": "string"
        },
        "token_type": {
          "type": "string",
          "enum": [
            "Bearer"
          ]
        },
        "expires_in": {
          "type": "integer"
        }
      }
    },
    "Token": {
      "type": "object",
      "properties": {
        "accessToken": {
          "type": "string"
        },
        "tokenType": {
          "type": "string",
          "enum": [
            "Bearer"
          ]
        },
        "expiresIn": {
          "type": "integer"
        }
      }
    },
    "EmailVerification": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "expiresIn": {
          "type": "integer"
        },
        "createdAt": {
          "type": "string",
          "format": "datetime"
        }
      }
    },
    "PhoneNumberVerification": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string"
        },
        "status": {
          "type": "string",
          "enum": [
            "requested",
            "verified"
          ]
        },
        "expiresIn": {
          "type": "integer"
        },
        "createdAt": {
          "type": "string",
          "format": "datetime"
        },
        "verifiedAt": {
          "type": "string",
          "format": "datetime",
          "x-nullable": true
        }
      }
    },
    "SingupBody": {
      "type": "object",
      "required": [
        "email",
        "password",
        "phoneNumber",
        "phoneNumberVerificationID"
      ],
      "properties": {
        "email": {
          "$ref": "#/definitions/Email"
        },
        "password": {
          "$ref": "#/definitions/Password"
        },
        "phoneNumber": {
          "$ref": "#/definitions/PhoneNumber"
        },
        "phoneNumberVerificationID": {
          "type": "string"
        }
      }
    },
    "CreatePhoneNumberVerificationBody": {
      "type": "object",
      "required": [
        "phoneNumber"
      ],
      "properties": {
        "phoneNumber": {
          "type": "string",
          "format": "^0[789]0[0-9]{8}$"
        }
      }
    },
    "CheckPhoneNumberVerificationBody": {
      "type": "object",
      "required": [
        "verificationCode"
      ],
      "properties": {
        "verificationCode": {
          "type": "string"
        }
      }
    },
    "CreateEmailVerificationBody": {
      "type": "object",
      "required": [
        "email"
      ],
      "properties": {
        "email": {
          "type": "string",
          "format": "email"
        }
      }
    },
    "ChangeMyEmailBody": {
      "type": "object",
      "required": [
        "email"
      ],
      "properties": {
        "email": {
          "type": "string",
          "format": "email"
        }
      }
    },
    "ChangeMyPhoneNumberBody": {
      "type": "object",
      "required": [
        "phoneNumber",
        "phoneNumberVerificationID"
      ],
      "properties": {
        "phoneNumber": {
          "$ref": "#/definitions/PhoneNumber"
        },
        "phoneNumberVerificationID": {
          "type": "string"
        }
      }
    },
    "Email": {
      "type": "string",
      "format": "email"
    },
    "Password": {
      "type": "string",
      "format": "^[0-9A-Za-z!-~]{8,40}$",
      "example": "sekai-no-8maki"
    },
    "PhoneNumber": {
      "type": "string",
      "format": "^0[789]0[0-9]{8}$",
      "example": "08012345678"
    }
  },
  "basePath": "/v1",
  "securityDefinitions": {
    "OAuth2": {
      "type": "oauth2",
      "flow": "password",
      "tokenUrl": "https://localhost:8509/v1/oauth2/token",
      "scopes": {
        "read": "Grant read-only access to all your data except for the account and user info",
        "write": "Grant write-only access to all your data except for the account and user info",
        "profile": "Grant read-only access to the account and user info only"
      }
    },
    "Authorization": {
      "type": "apiKey",
      "in": "header",
      "description": "",
      "name": "Bearer Oauth2 Token"
    }
  },
  "security": [
    {
      "Authorization": []
    }
  ]
}
