~vpzom/lotide

542c56d6fe008e5f9fa95c583e76b4ed6ea41c74 — Colin Reeder 10 days ago 7127859 + 61adafd
Merge branch 'api-changes' into master
4 files changed, 58 insertions(+), 30 deletions(-)

M openapi/openapi.json
M src/routes/api/mod.rs
M src/routes/api/posts.rs
M src/routes/api/users.rs
M openapi/openapi.json => openapi/openapi.json +19 -17
@@ 16,6 16,16 @@
				"type": "string",
				"enum": ["hot", "new"]
			},
			"LoginUserInfo": {
				"type": "object",
				"required": ["id", "username", "is_site_admin", "has_unread_notification"],
				"properties": {
					"id": {"type": "integer"},
					"username": {"type": "string"},
					"is_site_admin": {"type": "boolean"},
					"has_unread_notification": {"type": "boolean"}
				}
			},
			"MinimalCommentInfo": {
				"type": "object",
				"required": ["id"],


@@ 905,9 915,12 @@
							"application/json": {
								"schema": {
									"type": "object",
									"required": ["token"],
									"required": ["token", "user"],
									"properties": {
										"token": {"type": "string"}
										"token": {"type": "string"},
										"user": {
											"$ref": "#/components/schemas/LoginUserInfo"
										}
									}
								}
							}


@@ 929,14 942,7 @@
									"required": ["user"],
									"properties": {
										"user": {
											"type": "object",
											"required": ["id", "name", "is_site_admin", "has_unread_notifications"],
											"properties": {
												"id": {"type": "integer"},
												"name": {"type": "string"},
												"is_site_admin": {"type": "boolean"},
												"has_unread_notifications": {"type": "boolean"}
											}
											"$ref": "#/components/schemas/LoginUserInfo"
										}
									}
								}


@@ 1099,11 1105,11 @@
								"schema": {
									"allOf": [{"$ref": "#/components/schemas/PostListPost"}],
									"type": "object",
									"required": ["approved", "score", "comments"],
									"required": ["approved", "score", "replies"],
									"properties": {
										"approved": {"type": "boolean"},
										"score": {"type": "integer"},
										"comments": {
										"replies": {
											"type": "array",
											"items": {"$ref": "#/components/schemas/PostCommentInfo"}
										},


@@ 1294,11 1300,7 @@
									"required": ["user"],
									"properties": {
										"user": {
											"type": "object",
											"required": ["id"],
											"properties": {
												"id": {"type": "integer"}
											}
											"$ref": "#/components/schemas/LoginUserInfo"
										},
										"token": {
											"type": "string"

M src/routes/api/mod.rs => src/routes/api/mod.rs +25 -7
@@ 65,6 65,14 @@ struct RespMinimalAuthorInfo<'a> {
}

#[derive(Serialize)]
struct RespLoginUserInfo<'a> {
    id: UserLocalID,
    username: &'a str,
    is_site_admin: bool,
    has_unread_notifications: bool,
}

#[derive(Serialize)]
struct JustUser<'a> {
    user: RespMinimalAuthorInfo<'a>,
}


@@ 322,7 330,7 @@ async fn route_unstable_logins_create(

    let row = db
        .query_opt(
            "SELECT id, passhash FROM person WHERE LOWER(username)=LOWER($1) AND local",
            "SELECT id, username, passhash, is_site_admin, EXISTS(SELECT 1 FROM notification WHERE to_user = person.id AND created_at > person.last_checked_notifications) FROM person WHERE LOWER(username)=LOWER($1) AND local",
            &[&body.username],
        )
        .await?


@@ 334,7 342,8 @@ async fn route_unstable_logins_create(
        })?;

    let id = UserLocalID(row.get(0));
    let passhash: Option<String> = row.get(1);
    let username: &str = row.get(1);
    let passhash: Option<String> = row.get(2);

    let passhash = passhash.ok_or_else(|| {
        crate::Error::UserError(crate::simple_response(


@@ 352,7 361,14 @@ async fn route_unstable_logins_create(
    if correct {
        let token = insert_token(id, &db).await?;

        crate::json_response(&serde_json::json!({"token": token.to_string()}))
        crate::json_response(
            &serde_json::json!({"token": token.to_string(), "user": RespLoginUserInfo {
                id,
                username,
                is_site_admin: row.get(3),
                has_unread_notifications: row.get(4),
            }}),
        )
    } else {
        Ok(crate::simple_response(
            hyper::StatusCode::FORBIDDEN,


@@ 371,12 387,14 @@ async fn route_unstable_logins_current_get(
    let user = crate::require_login(&req, &db).await?;

    let row = db.query_one("SELECT username, is_site_admin, EXISTS(SELECT 1 FROM notification WHERE to_user = person.id AND created_at > person.last_checked_notifications) FROM person WHERE id=$1", &[&user]).await?;
    let username: &str = row.get(0);
    let is_site_admin: bool = row.get(1);
    let has_notifications: bool = row.get(2);

    crate::json_response(&serde_json::json!({
        "user": {"id": user, "name": username, "is_site_admin": is_site_admin, "has_unread_notifications": has_notifications}
        "user": RespLoginUserInfo {
            id: user,
            username: row.get(0),
            is_site_admin: row.get(1),
            has_unread_notifications: row.get(2),
        },
    }))
}


M src/routes/api/posts.rs => src/routes/api/posts.rs +2 -2
@@ 254,7 254,7 @@ async fn route_unstable_posts_get(
        post: &'a RespPostListPost<'a>,
        approved: bool,
        score: i64,
        comments: Vec<RespPostCommentInfo<'a>>,
        replies: Vec<RespPostCommentInfo<'a>>,
        #[serde(skip_serializing_if = "Option::is_none")]
        your_vote: Option<Option<crate::Empty>>,
    }


@@ 344,7 344,7 @@ async fn route_unstable_posts_get(

            let output = RespPostInfo {
                post: &post,
                comments,
                replies: comments,
                approved: row.get(14),
                score: row.get(13),
                your_vote,

M src/routes/api/users.rs => src/routes/api/users.rs +12 -4
@@ 1,6 1,7 @@
use super::{
    handle_common_posts_list, MaybeIncludeYour, RespAvatarInfo, RespMinimalAuthorInfo,
    RespMinimalCommentInfo, RespMinimalCommunityInfo, RespMinimalPostInfo, RespThingInfo,
    handle_common_posts_list, MaybeIncludeYour, RespAvatarInfo, RespLoginUserInfo,
    RespMinimalAuthorInfo, RespMinimalCommentInfo, RespMinimalCommunityInfo, RespMinimalPostInfo,
    RespThingInfo,
};
use crate::{CommentLocalID, CommunityLocalID, PostLocalID, UserLocalID};
use serde_derive::{Deserialize, Serialize};


@@ 156,11 157,18 @@ async fn route_unstable_users_create(
        UserLocalID(row.get(0))
    };

    let info = RespLoginUserInfo {
        id: user_id,
        username: &body.username,
        is_site_admin: false,
        has_unread_notifications: false,
    };

    let output = if body.login {
        let token = super::insert_token(user_id, &db).await?;
        serde_json::json!({"user": {"id": user_id}, "token": token.to_string()})
        serde_json::json!({"user": info, "token": token.to_string()})
    } else {
        serde_json::json!({"user": {"id": user_id}})
        serde_json::json!({ "user": info })
    };

    crate::json_response(&output)