Skip to content

Commit

Permalink
Update coral
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelthomas2774 committed Jul 27, 2022
1 parent fe725f9 commit 85a9193
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 4 deletions.
25 changes: 25 additions & 0 deletions src/api/coral-types.ts
Expand Up @@ -34,7 +34,17 @@ export enum CoralStatus {
MULTIPLE_LOGIN = 9426,
UPGRADE_REQUIRED = 9427,
ACCOUNT_DISABLED = 9428,
RATE_LIMIT_EXCEEDED = 9437,
MEMBERSHIP_REQUIRED = 9450,
INVALID_FRIEND_REQUEST = 9460,
SENDER_FRIEND_LIMIT_EXCEEDED = 9461,
RECEIVER_FRIEND_LIMIT_EXCEEDED = 9462,
FRIEND_REQUEST_NOT_ACCEPTED = 9463,
DUPLICATE_FRIEND_REQUEST = 9464,
PRECONDITION_FAILED = 9465,
RESOURCE_LIMIT_EXCEEDED = 9466,
ALREADY_FRIEND = 9467,
SENDER_BLOCKS_RECEIVER_FRIEND_REQUEST = 9468,
SERVICE_CLOSED = 9499,
INTERNAL_SERVER_ERROR = 9500,
SERVICE_UNAVAILABLE = 9501,
Expand Down Expand Up @@ -128,6 +138,21 @@ export interface Game {
sysDescription: string;
}

/** /v3/Friend/CreateFriendCodeUrl */
export interface FriendCodeUrl {
url: string;
friendCode: string;
}

/** /v3/Friend/GetUserByFriendCode, /v3/Friend/GetUserByFriendCodeHash */
export interface FriendCodeUser {
id: number;
nsaId: string;
imageUrl: string;
name: string;
extras: {};
}

/** /v1/Game/ListWebServices */
export type WebServices = WebService[];

Expand Down
29 changes: 27 additions & 2 deletions src/api/coral.ts
Expand Up @@ -2,7 +2,7 @@ import fetch, { Response } from 'node-fetch';
import { v4 as uuidgen } from 'uuid';
import createDebug from 'debug';
import { f, FlapgIid } from './f.js';
import { AccountLogin, AccountToken, Announcements, CurrentUser, CurrentUserPermissions, Event, Friends, GetActiveEventResult, PresencePermissions, User, WebServices, WebServiceToken, CoralErrorResponse, CoralResponse, CoralStatus, CoralSuccessResponse } from './coral-types.js';
import { AccountLogin, AccountToken, Announcements, CurrentUser, CurrentUserPermissions, Event, Friends, GetActiveEventResult, PresencePermissions, User, WebServices, WebServiceToken, CoralErrorResponse, CoralResponse, CoralStatus, CoralSuccessResponse, FriendCodeUser, FriendCodeUrl } from './coral-types.js';
import { getNintendoAccountToken, getNintendoAccountUser, NintendoAccountUser } from './na.js';
import { ErrorResponse } from './util.js';
import { JwtPayload } from '../util/jwt.js';
Expand All @@ -12,12 +12,15 @@ const debug = createDebug('nxapi:api:coral');

const ZNCA_PLATFORM = 'Android';
const ZNCA_PLATFORM_VERSION = '8.0.0';
const ZNCA_VERSION = '2.1.1';
const ZNCA_VERSION = '2.2.0';
const ZNCA_USER_AGENT = `com.nintendo.znca/${ZNCA_VERSION}(${ZNCA_PLATFORM}/${ZNCA_PLATFORM_VERSION})`;

const ZNC_URL = 'https://api-lp1.znc.srv.nintendo.net';
export const ZNCA_CLIENT_ID = '71b963c1b7b6d119';

const FRIEND_CODE = /^\d{4}-\d{4}-\d{4}$/;
const FRIEND_CODE_HASH = /^[A-Za-z0-9]{10}$/;

export default class CoralApi {
onTokenExpired: ((data: CoralErrorResponse, res: Response) => Promise<void>) | null = null;
/** @internal */
Expand Down Expand Up @@ -123,10 +126,32 @@ export default class CoralApi {
});
}

async getUserByFriendCode(friend_code: string, hash?: string) {
if (!FRIEND_CODE.test(friend_code)) throw new Error('Invalid friend code');
if (hash && !FRIEND_CODE_HASH.test(hash)) throw new Error('Invalid friend code hash');

return hash ? this.call<FriendCodeUser>('/v3/Friend/GetUserByFriendCodeHash', {
friendCode: friend_code,
friendCodeHash: hash,
}) : this.call<FriendCodeUser>('/v3/Friend/GetUserByFriendCode', {
friendCode: friend_code,
});
}

async sendFriendRequest(nsa_id: string) {
return this.call<{}>('/v3/FriendRequest/Create', {
nsaId: nsa_id,
});
}

async getCurrentUser() {
return this.call<CurrentUser>('/v3/User/ShowSelf');
}

async getFriendCodeUrl() {
return this.call<FriendCodeUrl>('/v3/Friend/CreateFriendCodeUrl');
}

async getCurrentUserPermissions() {
return this.call<CurrentUserPermissions>('/v3/User/Permissions/ShowSelf');
}
Expand Down
1 change: 1 addition & 0 deletions src/app/main/ipc.ts
Expand Up @@ -164,6 +164,7 @@ export function setupIpc(appinstance: App, ipcMain: IpcMain) {
ipcMain.handle('nxapi:webserviceapi:requestGameWebToken', e => webserviceipc.requestGameWebToken(e));
ipcMain.handle('nxapi:webserviceapi:restorePersistentData', e => webserviceipc.restorePersistentData(e));
ipcMain.handle('nxapi:webserviceapi:storePersistentData', (e, data: string) => webserviceipc.storePersistentData(e, data));
ipcMain.handle('nxapi:webserviceapi:completeLoading', e => webserviceipc.completeLoading(e));

store.on('update-nintendo-accounts', () => sendToAllWindows('nxapi:accounts:shouldrefresh'));
store.on('update-discord-presence-source', () => sendToAllWindows('nxapi:discord:shouldrefresh'));
Expand Down
6 changes: 6 additions & 0 deletions src/app/main/webservices.ts
Expand Up @@ -338,4 +338,10 @@ export class WebServiceIpc {
const key = 'WebServicePersistentData.' + nsoAccount.user.nsaId + '.' + webservice.id;
await store.storage.setItem(key, data);
}

async completeLoading(event: IpcMainInvokeEvent): Promise<void> {
const {nsoAccount, webservice} = this.getWindowData(event.sender);

debug('Web service %s, user %s, called completeLoading', webservice.name, nsoAccount.user.name);
}
}
1 change: 1 addition & 0 deletions src/app/preload-webservice/ipc.ts
Expand Up @@ -14,6 +14,7 @@ const ipc = {
requestGameWebToken: () => ipcRenderer.invoke('nxapi:webserviceapi:requestGameWebToken') as Promise<string>,
restorePersistentData: () => ipcRenderer.invoke('nxapi:webserviceapi:restorePersistentData') as Promise<string | undefined>,
storePersistentData: (data: string) => ipcRenderer.invoke('nxapi:webserviceapi:storePersistentData', data) as Promise<void>,
completeLoading: () => ipcRenderer.invoke('nxapi:webserviceapi:completeLoading') as Promise<void>,
};

export default ipc;
Expand Down
61 changes: 59 additions & 2 deletions src/app/preload-webservice/znca-js-api.ts
Expand Up @@ -29,7 +29,7 @@ declare global {
onPersistentDataRestore?: (data: string) => void;
// NookLink
storePersistentData?: (data: string) => void;
onPersistentDataStore?: () => void;
onPersistentDataStore?: (data: string) => void;

// NookLink
openQRCodeReader?: (data: string) => void;
Expand All @@ -40,6 +40,18 @@ declare global {
closeQRCodeReader?: () => void;
// NookLink
closeQRCodeReaderFromPhotoLibrary?: () => void;

// Unused
sendMessage?(data: string): void;
// Unused
copyToClipboard?(data: string): void;

openQRCodeReaderForCheckin?(data: string): void;
onQRCodeReadForCheckin?(data: string): void;
downloadImages?(imagesJson: string): void;
completeLoading?(): void;
closeWebView?(): void;
reloadExtension?(): void;
}
}

Expand Down Expand Up @@ -109,7 +121,7 @@ function storePersistentData(data: string) {
debug('storePersistentData called', data);

ipc.storePersistentData(data).then(() => {
window.onPersistentDataStore?.call(null);
window.onPersistentDataStore?.call(null, '');
});
}

Expand Down Expand Up @@ -146,7 +158,52 @@ function closeQrCodeReaderFromPhotoLibrary() {
//
}

function openQRCodeReaderForCheckin(data: string) {
//

Promise.resolve().then(() => {
const base64EncodeText = '';
window.onQRCodeReadForCheckin?.call(null, base64EncodeText);
});
}

window.openQRCodeReader = openQrCodeReader;
window.openQRCodeReaderFromPhotoLibrary = openQrCodeReaderFromPhotoLibrary;
window.closeQRCodeReader = closeQrCodeReader;
window.closeQRCodeReaderFromPhotoLibrary = closeQrCodeReaderFromPhotoLibrary;
window.openQRCodeReaderForCheckin = openQRCodeReaderForCheckin;

//
// Other
//

function sendMessage(data: string) {
//
}

function copyToClipboard(data: string) {
//
}

function downloadImages(imagesJson: string) {
//
}

function completeLoading() {
ipc.completeLoading();
}

function closeWebView() {
window.close();
}

function reloadExtension() {
//
}

window.sendMessage = sendMessage;
window.copyToClipboard = copyToClipboard;
window.downloadImages = downloadImages;
window.completeLoading = completeLoading;
window.closeWebView = closeWebView;
window.reloadExtension = reloadExtension;

0 comments on commit 85a9193

Please sign in to comment.