[mastodon-client] POST /apps

This commit is contained in:
Laura Hausmann 2023-09-29 00:49:01 +02:00
parent 5e20c3ae06
commit f57239fc58
Signed by: zotan
GPG key ID: D044E84C5BE01605
3 changed files with 171 additions and 14 deletions

View file

@ -1,8 +1,6 @@
import megalodon, { MegalodonInterface } from "megalodon";
import Router from "@koa/router";
import { koaBody } from "koa-body";
import { getClient } from "../ApiMastodonCompatibleService.js";
import bodyParser from "koa-bodyparser";
import { AuthHelpers } from "@/server/api/mastodon/helpers/auth.js";
import { convertId, IdType } from "@/misc/convert-id.js";
const readScope = [
"read:account",
@ -43,8 +41,6 @@ const writeScope = [
export function apiAuthMastodon(router: Router): void {
router.post("/v1/apps", async (ctx) => {
const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`;
const client = getClient(BASE_URL, "");
const body: any = ctx.request.body || ctx.request.query;
try {
let scope = body.scopes;
@ -57,20 +53,15 @@ export function apiAuthMastodon(router: Router): void {
const scopeArr = Array.from(pushScope);
const red = body.redirect_uris;
const appData = await client.registerApp(body.client_name, {
scopes: scopeArr,
redirect_uris: red,
website: body.website,
});
const appData = await AuthHelpers.registerApp(body['client_name'], scopeArr, red, body['website']);
const returns = {
id: Math.floor(Math.random() * 100).toString(),
id: convertId(appData.id, IdType.MastodonId),
name: appData.name,
website: body.website,
redirect_uri: red,
client_id: Buffer.from(appData.url || "").toString("base64"),
client_id: Buffer.from(appData.url ?? "").toString("base64"),
client_secret: appData.clientSecret,
};
console.log(returns);
ctx.body = returns;
} catch (e: any) {
console.error(e);

View file

@ -0,0 +1,123 @@
/**
* OAuth
* Response data when oauth request.
**/
namespace OAuth {
export type AppDataFromServer = {
id: string;
name: string;
website: string | null;
redirect_uri: string;
client_id: string;
client_secret: string;
};
export type TokenDataFromServer = {
access_token: string;
token_type: string;
scope: string;
created_at: number;
expires_in: number | null;
refresh_token: string | null;
};
export class AppData {
public url: string | null;
public session_token: string | null;
constructor(
public id: string,
public name: string,
public website: string | null,
public redirect_uri: string,
public client_id: string,
public client_secret: string,
) {
this.url = null;
this.session_token = null;
}
/**
* Serialize raw application data from server
* @param raw from server
*/
static from(raw: AppDataFromServer) {
return new this(
raw.id,
raw.name,
raw.website,
raw.redirect_uri,
raw.client_id,
raw.client_secret,
);
}
get redirectUri() {
return this.redirect_uri;
}
get clientId() {
return this.client_id;
}
get clientSecret() {
return this.client_secret;
}
}
export class TokenData {
public _scope: string;
constructor(
public access_token: string,
public token_type: string,
scope: string,
public created_at: number,
public expires_in: number | null = null,
public refresh_token: string | null = null,
) {
this._scope = scope;
}
/**
* Serialize raw token data from server
* @param raw from server
*/
static from(raw: TokenDataFromServer) {
return new this(
raw.access_token,
raw.token_type,
raw.scope,
raw.created_at,
raw.expires_in,
raw.refresh_token,
);
}
/**
* OAuth Aceess Token
*/
get accessToken() {
return this.access_token;
}
get tokenType() {
return this.token_type;
}
get scope() {
return this._scope;
}
/**
* Application ID
*/
get createdAt() {
return this.created_at;
}
get expiresIn() {
return this.expires_in;
}
/**
* OAuth Refresh Token
*/
get refreshToken() {
return this.refresh_token;
}
}
}
export default OAuth;

View file

@ -0,0 +1,43 @@
import OAuth from "@/server/api/mastodon/entities/oauth/oauth.js";
import { secureRndstr } from "@/misc/secure-rndstr.js";
import { Apps, AuthSessions } from "@/models/index.js";
import { genId } from "@/misc/gen-id.js";
import { v4 as uuid } from "uuid";
import config from "@/config/index.js";
export class AuthHelpers {
public static async registerApp(name: string, scopes: string[], redirect_uris: string, website: string | null): Promise<OAuth.AppData> {
const secret = secureRndstr(32);
const app = await Apps.insert({
id: genId(),
createdAt: new Date(),
userId: null,
name: name,
description: '',
permission: scopes,
callbackUrl: redirect_uris,
secret: secret,
}).then((x) => Apps.findOneByOrFail(x.identifiers[0]));
const appdataPre: OAuth.AppDataFromServer = {
id: app.id,
name: app.name,
website: website,
client_id: "",
client_secret: app.secret,
redirect_uri: redirect_uris!
}
const appdata = OAuth.AppData.from(appdataPre);
const token = uuid();
const session = await AuthSessions.insert({
id: genId(),
createdAt: new Date(),
appId: app.id,
token: token,
}).then((x) => AuthSessions.findOneByOrFail(x.identifiers[0]));
appdata.url = `${config.authUrl}/${session.token}`;
appdata.session_token = session.token;
return appdata;
}
}