Files
ncd-fe/packages/pl-api/lib/client/oauth.ts
nicole mikołajczyk a4dd5e0358 pl-api: reimport TypeObject, need to eep
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
2026-02-27 02:32:38 +01:00

146 lines
4.4 KiB
TypeScript

import * as v from 'valibot';
import { authorizationServerMetadataSchema, tokenSchema, userInfoSchema } from '@/entities';
import { ICESHRIMP_NET } from '../features';
import type { PlApiBaseClient } from '@/client-base';
import type {
GetTokenParams,
MfaChallengeParams,
OauthAuthorizeParams,
RevokeTokenParams,
} from '@/params/oauth';
import type { EmptyObject } from '@/utils/types';
const oauth = (client: PlApiBaseClient) => ({
/**
* Authorize a user
* Displays an authorization form to the user. If approved, it will create and return an authorization code, then redirect to the desired `redirect_uri`, or show the authorization code if `urn:ietf:wg:oauth:2.0:oob` was requested. The authorization code can be used while requesting a token to obtain access to user-level methods.
* @see {@link https://docs.joinmastodon.org/methods/oauth/#authorize}
*/
authorize: async (params: OauthAuthorizeParams) => {
const response = await client.request('/oauth/authorize', { params, contentType: '' });
return v.parse(v.string(), response.json);
},
/**
* Obtain a token
* Obtain an access token, to be used during API calls that are not public.
* @see {@link https://docs.joinmastodon.org/methods/oauth/#token}
*/
getToken: async (params: GetTokenParams) => {
if (client.features.version.software === ICESHRIMP_NET && params.grant_type === 'password') {
const loginResponse = (
await client.request<{
token: string;
}>('/api/iceshrimp/auth/login', {
method: 'POST',
body: {
username: params.username,
password: params.password,
},
})
).json;
client.setIceshrimpAccessToken(loginResponse.token);
const mastodonTokenResponse = (
await client.request<{
id: string;
token: string;
created_at: string;
scopes: Array<string>;
}>('/api/iceshrimp/sessions/mastodon', {
method: 'POST',
body: {
appName: params.client_id,
scopes: params.scope?.split(' '),
flags: {
supportsHtmlFormatting: true,
autoDetectQuotes: false,
isPleroma: true,
supportsInlineMedia: true,
},
},
})
).json;
return v.parse(tokenSchema, {
access_token: mastodonTokenResponse.token,
token_type: 'Bearer',
scope: mastodonTokenResponse.scopes.join(' '),
created_at: new Date(mastodonTokenResponse.created_at).getTime(),
id: mastodonTokenResponse.id,
});
}
const response = await client.request('/oauth/token', {
method: 'POST',
body: params,
contentType: '',
});
return v.parse(tokenSchema, { scope: params.scope || '', ...response.json });
},
/**
* Revoke a token
* Revoke an access token to make it no longer valid for use.
* @see {@link https://docs.joinmastodon.org/methods/oauth/#revoke}
*/
revokeToken: async (params: RevokeTokenParams) => {
const response = await client.request<EmptyObject>('/oauth/revoke', {
method: 'POST',
body: params,
contentType: '',
});
client.socket?.close();
return response.json;
},
/**
* Retrieve user information
* Retrieves standardised OIDC claims about the currently authenticated user.
* see {@link https://docs.joinmastodon.org/methods/oauth/#userinfo}
*/
userinfo: async () => {
const response = await client.request('/oauth/userinfo');
return v.parse(userInfoSchema, response.json);
},
authorizationServerMetadata: async () => {
const response = await client.request('/.well-known/oauth-authorization-server');
return v.parse(authorizationServerMetadataSchema, response.json);
},
/**
* Get a new captcha
* @see {@link https://docs.pleroma.social/backend/development/API/pleroma_api/#apiv1pleromacaptcha}
*/
getCaptcha: async () => {
const response = await client.request('/api/pleroma/captcha');
return v.parse(
v.intersect([
v.object({
type: v.string(),
}),
v.record(v.string(), v.any()),
]),
response.json,
);
},
mfaChallenge: async (params: MfaChallengeParams) => {
const response = await client.request('/oauth/mfa/challenge', { method: 'POST', body: params });
return v.parse(tokenSchema, response.json);
},
});
export { oauth };