Files
linux-odyssey/server/swagger.yaml

744 lines
19 KiB
YAML

openapi: 3.0.0
servers:
- url: /api/v1
- url: https://odyssey.wancat.cc/api/v1
- url: http://localhost:3000/api/v1
info:
description: Linux Odyssey API
version: '1.0.0'
title: Session API
contact:
email: wancat@wancat.cc
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: admins
description: Secured Admin-only calls
- name: developers
description: Operations available to regular developers
paths:
/sessions:
get:
tags:
- signed-in
summary: list existing sessions of current user
security:
- cookieAuth: []
parameters:
- in: query
name: questId
description: find sessions by quest id
schema:
type: string
- in: query
name: status
description: find sessions by status
schema:
type: string
enum: [active, finished, inactive]
responses:
'200':
description: list of existing session
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/SessionSummary'
post:
summary: create a new session for current user
tags:
- signed-in
security:
- cookieAuth: []
requestBody:
description: session data
content:
application/json:
schema:
type: object
properties:
questId:
type: string
example: helloworld
responses:
'201':
description: session created
content:
application/json:
schema:
$ref: '#/components/schemas/Session'
'400':
description: Invalid input
content:
application/json:
schema:
type: object
properties:
message:
type: string
'403':
description: This quest is locked.
/sessions/active:
post:
summary: 'Get or create an active session.'
tags:
- signed-in
description: 'This endpoint returns the latest active session for the user, or creates a new one if no active session exists.'
requestBody:
required: true
content:
application/json:
schema:
type: 'object'
required:
- questId
properties:
questId:
type: 'string'
description: 'The ID of the quest.'
example: 'helloworld'
responses:
200:
description: 'Return a active session.'
content:
application/json:
schema:
$ref: '#/components/schemas/Session'
400:
description: 'Bad Request. The request is invalid or malformed.'
403:
description: This quest is locked.
500:
description: 'Internal Server Error.'
/sessions/{sessionId}:
get:
tags:
- signed-in
summary: get a specific session of current user by ID
security:
- cookieAuth: []
parameters:
- in: path
name: sessionId
description: ID of the session to retrieve
required: true
schema:
type: string
format: objectId
example: 64b7a3a3c182b4826dd1aaa1
responses:
'200':
description: the session
content:
application/json:
schema:
$ref: '#/components/schemas/Session'
'404':
description: cannot find specific session
content:
application/json:
schema:
type: object
properties:
message:
type: string
/auth/register:
post:
summary: Register a new user
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
username:
type: string
format: username
example: alex
email:
type: string
format: email
example: alex@example.com
password:
type: string
format: password
example: 123456
responses:
'201':
description: User created
headers:
Set-Cookie:
schema:
type: string
example: connect.sid=s%3Aq1Z; Path=/; HttpOnly; SameSite=Strict; Secure
content:
application/json:
schema:
type: object
properties:
token:
type: string
description: Access token
example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
'400':
description: Bad Request
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Missing username, email or password
'409':
description: Conflict
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: User already exists
/auth/register-from-session:
post:
summary: Register a new user from a session, for social login to pick a username
security:
- cookieAuth: []
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
username:
type: string
format: username
example: alex
responses:
'201':
description: User created
headers:
Set-Cookie:
schema:
type: string
example: connect.sid=s%3Aq1Z; Path=/; HttpOnly; SameSite=Strict; Secure
/auth/login:
post:
summary: Log in a user
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
username:
type: string
format: username
example: alex
password:
type: string
format: password
example: 123456
responses:
'200':
description: User logged in
headers:
Set-Cookie:
schema:
type: string
example: connect.sid=s%3Aq1Z; Path=/; HttpOnly; SameSite=Strict; Secure
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Logged in successfully
'400':
description: Bad Request
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Missing username or password
'401':
description: Unauthorized
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Incorrect username or password
/auth/logout:
post:
summary: Log out a user
tags:
- signed-in
security:
- cookieAuth: []
responses:
'200':
description: User logged out
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Logged out successfully
/auth/check-username:
get:
summary: Check if the username is already taken
parameters:
- in: query
name: username
description: username to check
required: true
schema:
type: string
format: username
example: alex
- in: query
name: email
description: email to check
required: true
schema:
type: string
format: email
example: alex@example.com
responses:
'200':
description: Username / Email checking result
content:
application/json:
schema:
type: object
properties:
type:
type: string
example: Username is available
available:
type: boolean
example: true
'400':
description: Bad Request
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: Username is already taken
/auth/available-methods:
get:
summary: Get available login methods
responses:
'200':
description: Available login methods
content:
application/json:
schema:
type: object
properties:
local:
type: boolean
example: true
github:
type: boolean
example: true
google:
type: boolean
example: true
facebook:
type: boolean
example: true
/auth/check-session:
get:
summary: Check if the session is valid
responses:
'200':
description: Result
content:
application/json:
schema:
type: object
properties:
loggedIn:
type: boolean
example: true
/auth/google:
get:
summary: Initiate OAuth2 login with Google
operationId: initiateOAuth
security:
- GoogleOAuth: []
responses:
302:
description: Redirect to Google's OAuth 2.0 authorization endpoint
500:
description: Internal Server Error
/auth/google/callback:
get:
summary: OAuth2 callback endpoint
operationId: oauthCallback
parameters:
- name: code
in: query
description: Authorization code from Google
required: true
schema:
type: string
responses:
200:
description: Successful Operation
400:
description: Bad Request
500:
description: Internal Server Error
/quests:
get:
summary: Get quests list
responses:
'200':
description: Quests summary list
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/QuestSummary'
/quests/{questId}:
get:
summary: get a quest's detail by name
parameters:
- in: path
name: questId
description: name of the quest to retrieve
required: true
schema:
type: string
responses:
'200':
description: the quest
content:
application/json:
schema:
$ref: '#/components/schemas/Quest'
'404':
description: cannot find specific quest
content:
application/json:
schema:
type: object
properties:
message:
type: string
/commands:
post:
summary: Record a command that was executed in a session
tags:
- signed-in
security:
- cookieAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Command'
responses:
'201':
description: Command recorded successfully
content:
application/json:
schema:
$ref: '#/components/schemas/CommandResponse'
'400':
description: Invalid request body
'401':
description: Unauthorized
/ip:
get:
summary: Get client IP address
responses:
'200':
description: IP address
content:
application/json:
schema:
type: object
properties:
ip:
type: string
example: '127.0.0.1'
/users/me:
get:
summary: Get current user's profile
tags:
- signed-in
security:
- cookieAuth: []
responses:
'200':
description: User profile
content:
application/json:
schema:
$ref: '#/components/schemas/UserProfile'
'401':
description: Unauthorized
components:
schemas:
User:
type: object
properties:
_id:
type: string
format: objectId
example: 64b7a3a3c182b4826dd1aaa1
username:
type: string
example: 'alex'
email:
type: string
format: email
UserProfile:
type: object
properties:
username:
type: string
example: 'alex'
email:
type: string
format: email
example: alex@example.com
progress:
type: object
additionalProperties:
$ref: '#/components/schemas/Progress'
Progress:
type: object
properties:
questId:
type: string
example: helloworld
sessions:
type: array
items:
type: string
format: objectId
example: 64b7a3a3c182b4826dd1aaa1
completed:
type: boolean
example: true
startedAt:
type: string
format: date-time
example: 2020-01-01T00:00:00.000Z
finishedAt:
type: string
format: date-time
example: 2020-01-01T00:00:00.000Z
Quest:
type: object
properties:
_id:
type: string
example: helloworld
title:
type: string
example: Hello World
instruction:
type: string
example: 'In this quest, you need to learn how to use `ls` to list the file.'
order:
type: number
QuestSummary:
type: object
properties:
_id:
type: string
example: helloworld
title:
type: string
example: Hello World
order:
type: number
Session:
type: object
properties:
_id:
type: string
format: objectId
example: 64b7a3a3c182b4826dd1aaa1
user:
$ref: '#/components/schemas/User'
quest:
$ref: '#/components/schemas/Quest'
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
finishedAt:
type: string
format: date-time
hints:
type: array
items:
type: string
example: '`ls -al` to list detail information of all files.'
progress:
type: string
description: current stage id
example: helloworld
completed:
type: array
description: list of completed stage ids
items:
type: string
example: helloworld
SessionSummary:
type: object
properties:
_id:
type: string
format: objectId
example: 64b7a3a3c182b4826dd1aaa1
quest:
$ref: '#/components/schemas/Quest'
createdAt:
type: string
format: date-time
updatedAt:
type: string
format: date-time
finishedAt:
type: string
format: date-time
TreeNode:
type: object
properties:
name:
type: string
display:
type: boolean
children:
type: array
items:
$ref: '#/components/schemas/TreeNode'
Command:
type: object
required:
- pwd
- command
properties:
pwd:
type: string
example: '/root'
description: The current working directory
command:
type: string
example: 'ls -al /'
description: The command that was executed
output:
type: string
description: The output of the command
error:
type: string
description: The error message of the command
CommandResponse:
type: object
properties:
responses:
type: array
items:
$ref: '#/components/schemas/CommandResponseItem'
hints:
type: array
items:
type: string
example: '`ls -al` to list detail information of all files.'
end:
type: boolean
description: Whether the session has ended
CommandResponseItem:
type: object
required:
- type
- content
properties:
type:
type: string
enum: [narrative, dialogue]
content:
type: array
items:
type: string
example: 'You have completed the quest!'
color:
type: string
enum: [red, green, blue, yellow, purple, cyan, white, gray, black]
speaker:
type: string
example: 'Unix Spirit'
securitySchemes:
cookieAuth:
type: apiKey
in: cookie
name: connect.sid
GoogleOAuth:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://accounts.google.com/o/oauth2/auth
tokenUrl: https://accounts.google.com/o/oauth2/token
scopes:
# Define your scopes here
openid: OpenID
profile: User profile
email: User email