PageSourceSearch

https://ytyaru.github.io/js/misskey-authorizer-oauth.js

js ytyaru.github.io collected 2026-10-03 10:13:39 UTC 7,779 bytes, 141 lines download raw bytes

1// https://misskey.m544.net/docs/ja-JP/api
2class MisskeyAuthorizerOAuth {
3    constructor(domain='misskey.dev', permissions=null) {
4        const url = new URL(location.href)
5        url.searchParams.delete('code');
6        this.callbackUrl = url.href
7        this.domain = domain
8        //this.permission = (permissions) ? permissions : ['write:notes'] // https://misskey.m544.net/api-doc/#section/Permissions
9        this.permission = (Array.isArray(permissions)) ? permissions: ((typeof permissions === 'string' || permissions instanceof String)) ? permissions.split(',') : [''] //カンマ区切り。'write:notes' https://misskey.m544.net/api-doc/#section/Permissions
10        this.client = new MisskeyRestClient(this.domain)
11    }
12    //async authorize(text) {
13    async authorize(action=null, params=null) {
14        this.#createApp()
15        const app = await this.#createApp().catch(e=>alert(e))
16        console.debug(app)
17        sessionStorage.setItem(`misskey-domain`, this.domain);
18        //sessionStorage.setItem(`misskey-text`, text);
19        if (action) {
20            sessionStorage.setItem(`misskey-${this.domain}-callback-action`, (Array.isArray(action)) ? action.join('\n') : action)
21        }
22        if (params) {
23            sessionStorage.setItem(`misskey-${this.domain}-callback-action-params`, (Array.isArray(params)) ? params.map(p=>JSON.stringify(p)).join('\n') : JSON.stringify(params))
24        }
25        sessionStorage.setItem(`misskey-${this.domain}-oauth-secret`, app.secret);
26        //sessionStorage.setItem(`${domain}-app`, JSON.stringify(app));
27        //sessionStorage.setItem(`${domain}-id`, app.id);
28        this.#authorize(app.secret)
29    }
30    async #createApp() {
31        console.debug('----- apps(app/create) -----')
32        const params = {
33            name: `note requester`,
34            description: `request note`,
35            permission: this.permission,
36            callbackUrl: this.callbackUrl,
37        };
38        return await this.client.post('app/create', null, params)
39    }
40    async #authorize(appSecret) {
41        console.debug('----- authorize(auth/session/generate) -----')
42        const params = {appSecret:appSecret}
43        const res = await this.client.post('auth/session/generate', null, params)
44        console.debug(res)
45        sessionStorage.setItem(`misskey-${this.domain}-oauth-token`, res.token);
46        //const sleep = (second) => new Promise(resolve => setTimeout(resolve, second * 1000))
47        //await sleep(2)
48        window.location.href = res.url
49    }
50    async redirectCallback() {
51        const url = new URL(location.href)
52        console.debug('----- OAuth #redirectCallback() -----')
53        console.debug(url, url.href)
54        console.debug(url.searchParams.has('token'), sessionStorage.getItem(`misskey-domain`))
55        // misskey API auth/session/generate でリダイレクトされた場合(認証に成功した場合)
56        if (url.searchParams.has('token')) {
57            console.debug('------------- 認証に成功した(リダイレクトされた) -------------')
58            const domain = sessionStorage.getItem(`misskey-domain`);
59            const permission = sessionStorage.getItem(`misskey-${domain}-permission`);
60            const token = url.searchParams.get('token')
61            sessionStorage.setItem(`misskey-${domain}-oauth-token`, token)
62            // 認証コード(token)をURLパラメータから削除する
63            const params = url.searchParams;
64            params.delete('token');
65            history.replaceState('', '', url.pathname);
66            // トークンを取得して有効であることを確認しノートする
67            const secret = sessionStorage.getItem(`misskey-${domain}-oauth-secret`)
68            console.debug('----- authorized -----')
69            console.debug('secret:', secret)
70            console.debug('token:', token)
71            const json = await this.#getToken(sessionStorage.getItem(`misskey-${domain}-oauth-secret`), token)
72            console.debug('accessToken:', json.accessToken)
73            sessionStorage.setItem(`misskey-${domain}-oauth-accessToken`, json.accessToken);
74            const accessToken = json.accessToken
75            const i = await this.#getI(json.accessToken, sessionStorage.getItem(`misskey-${domain}-oauth-secret`))
76            sessionStorage.setItem(`misskey-${domain}-i`, i)
77            return i
78        }
79    }
80    async #getToken(appSecret, token) {
81        console.debug('----- token -----')
82        const params = {
83            appSecret: appSecret,
84            token: token,
85        };
86        return await this.client.post('auth/session/userkey', null, params)
87    }
88    async #getI(accessToken, appSecret) { return await this.#sha256(accessToken + appSecret) }
89    // https://scrapbox.io/nwtgck/SHA256%E3%81%AE%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E3%82%92JavaScript%E3%81%AEWeb%E6%A8%99%E6%BA%96%E3%81%AE%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%81%A0%E3%81%91%E3%81%A7%E8%A8%88%E7%AE%97%E3%81%99%E3%82%8B
90    async #sha256(str) {// const digest = await sha256("hello"); 
91        const buff = new Uint8Array([].map.call(str, (c) =>
91 c.charCodeAt(0))).buffer;
92        const digest = await crypto.subtle.digest('SHA-256', buff);
93        return [].map.call(new Uint8Array(digest), x => ('00' + x.toString(16)).slice(-2)).join('');
94    }
95    /*
96    async redirectCallback() {
97        const url = new URL(location.href)
98        console.debug('----- #redirectCallback() -----')
99        console.debug(url, url.href)
100        console.debug(url.searchParams.has('token'), sessionStorage.getItem(`misskey-domain`))
101        // misskey API auth/session/generate でリダイレクトされた場合(認証に成功した場合)
102        if (url.searchParams.has('token')) {
103            console.debug('------------- 認証に成功した(リダイレクトされた) -------------')
104            const domain = sessionStorage.getItem(`misskey-domain`);
105            //const client = new MisskeyNoteClient(domain)
106            const token = url.searchParams.get('token')
107            sessionStorage.setItem(`misskey-${domain}-oauth-token`, token)
108            // 認証コード(token)をURLパラメータから削除する
109            const params = url.searchParams;
110            params.delete('token');
111            history.replaceState('', '', url.pathname);
112            // トークンを取得して有効であることを確認しノートする
113            //const text = sessionStorage.getItem(`misskey-text`)
114            console.debug('----- authorized -----')
115            //console.debug('id:', sessionStorage.getItem(`${domain}-id`))
116            console.debug('secret:', sessionStorage.getItem(`misskey-${domain}-oauth-secret`))
117            console.debug('token:', token)
118            // client_id, client_secretはsessionStorageに保存しておく必要がある
119            //const json = await client.getToken(sessionStorage.getItem(`${domain}-secret`), token)
120            const json = await this.#getToken(sessionStorage.getItem(`misskey-${domain}-oauth-secret`), token)
121            //this.#errorApi(json)
122            console.debug('accessToken:', json.accessToken)
123            sessionStorage.setItem(`${domain}-accessToken`, json.accessToken);
124            const accessToken = json.accessToken
125            const i = await this.#getI(json.accessToken, sessionStorage.getItem(`misskey-${domain}-oauth-secret`))
126            sessionStorage.setItem(`${domain}-i`, i)
127            return i
128        }
129    }
130    */
131    /*
132    async note(i, text) {
133        console.debug('----- note -----')
134        console.debug(i)
135        console.debug(text)
136        const params = {i:i, text:text};
137        return await this.client.post('notes/create', null, params)
138    }
139    */
140}
141

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.