diff --git a/src/cli/nso/add-friend.ts b/src/cli/nso/add-friend.ts new file mode 100644 index 0000000..eeff4f0 --- /dev/null +++ b/src/cli/nso/add-friend.ts @@ -0,0 +1,70 @@ +import createDebug from 'debug'; +import type { Arguments as ParentArguments } from '../nso.js'; +import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js'; +import { initStorage } from '../../util/storage.js'; +import { getToken } from '../../common/auth/nso.js'; + +const debug = createDebug('cli:nso:add-friend'); + +export const command = 'add-friend '; +export const desc = 'Send a friend request using a user\'s friend code or NSA ID'; + +export function builder(yargs: Argv) { + return yargs.option('id', { + describe: 'Friend code or NSA ID', + type: 'string', + demandOption: true, + }).option('user', { + describe: 'Nintendo Account ID', + type: 'string', + }).option('token', { + describe: 'Nintendo Account session token', + type: 'string', + }); +} + +type Arguments = YargsArguments>; + +export async function handler(argv: ArgumentsCamelCase) { + const storage = await initStorage(argv.dataPath); + + const usernsid = argv.user ?? await storage.getItem('SelectedUser'); + const token: string = argv.token || + await storage.getItem('NintendoAccountToken.' + usernsid); + const {nso, data} = await getToken(storage, token, argv.zncProxyUrl); + + let nsa_id: string; + + if (/^\d{4}-\d{4}-\d{4}$/.test(argv.id)) { + // Friend code + + const user = await nso.getUserByFriendCode(argv.id); + nsa_id = user.result.nsaId; + + console.log('User', user.result); + } else if (/^[0-9a-f]{16}$/.test(argv.id)) { + // NSA ID + nsa_id = argv.id; + } else { + throw new Error('Invalid ID'); + } + + if (nsa_id === data.nsoAccount.user.nsaId) { + throw new Error('Cannot send a friend request to yourself'); + } + + await nso.sendFriendRequest(nsa_id); + + // Check if the user is now friends + // This means the other user had already sent this user a friend request, + // so sending them a friend request just accepted theirs + const friends = await nso.getFriendList(); + const friend = friends.result.friends.find(f => f.nsaId === nsa_id); + + if (friend) { + console.log('You are now friends with %s.', friend.name); + } else { + console.log('Friend request sent'); + console.log('The friend request can be accepted using a Nintendo Switch console, or by sending a friend request to your friend code: %s.', data.nsoAccount.user.links.friendCode.id); + } +} diff --git a/src/cli/nso/friendcode.ts b/src/cli/nso/friendcode.ts new file mode 100644 index 0000000..b442394 --- /dev/null +++ b/src/cli/nso/friendcode.ts @@ -0,0 +1,56 @@ +import createDebug from 'debug'; +import type { Arguments as ParentArguments } from '../nso.js'; +import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js'; +import { initStorage } from '../../util/storage.js'; +import { getToken } from '../../common/auth/nso.js'; + +const debug = createDebug('cli:nso:friendcode'); + +export const command = 'friendcode'; +export const desc = 'Get a friend code URL'; + +export function builder(yargs: Argv) { + return yargs.option('user', { + describe: 'Nintendo Account ID', + type: 'string', + }).option('token', { + describe: 'Nintendo Account session token', + type: 'string', + }).option('json', { + describe: 'Output raw JSON', + type: 'boolean', + }).option('json-pretty-print', { + describe: 'Output pretty-printed JSON', + type: 'boolean', + }); +} + +type Arguments = YargsArguments>; + +export async function handler(argv: ArgumentsCamelCase) { + const storage = await initStorage(argv.dataPath); + + const usernsid = argv.user ?? await storage.getItem('SelectedUser'); + const token: string = argv.token || + await storage.getItem('NintendoAccountToken.' + usernsid); + const {nso, data} = await getToken(storage, token, argv.zncProxyUrl); + + const announcements = await nso.getAnnouncements(); + const friends = await nso.getFriendList(); + const webservices = await nso.getWebServices(); + const activeevent = await nso.getActiveEvent(); + + const friendcodeurl = await nso.getFriendCodeUrl(); + + if (argv.jsonPrettyPrint) { + console.log(JSON.stringify(friendcodeurl.result, null, 4)); + return; + } + if (argv.json) { + console.log(JSON.stringify(friendcodeurl.result)); + return; + } + + console.warn('Friend code', friendcodeurl.result); + console.log(friendcodeurl.result.url); +} diff --git a/src/cli/nso/index.ts b/src/cli/nso/index.ts index 202df7f..52b6275 100644 --- a/src/cli/nso/index.ts +++ b/src/cli/nso/index.ts @@ -10,3 +10,6 @@ export * as presence from './presence.js'; export * as notify from './notify.js'; export * as httpServer from './http-server.js'; export * as zncProxyTokens from './znc-proxy-tokens.js'; +export * as friendcode from './friendcode.js'; +export * as lookup from './lookup.js'; +export * as addFriend from './add-friend.js'; diff --git a/src/cli/nso/lookup.ts b/src/cli/nso/lookup.ts new file mode 100644 index 0000000..d6d4001 --- /dev/null +++ b/src/cli/nso/lookup.ts @@ -0,0 +1,54 @@ +import createDebug from 'debug'; +import type { Arguments as ParentArguments } from '../nso.js'; +import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js'; +import { initStorage } from '../../util/storage.js'; +import { getToken } from '../../common/auth/nso.js'; + +const debug = createDebug('cli:nso:lookup'); + +export const command = 'lookup '; +export const desc = 'Lookup a user using their friend code'; + +export function builder(yargs: Argv) { + return yargs.option('id', { + describe: 'Friend code', + type: 'string', + demandOption: true, + }).option('user', { + describe: 'Nintendo Account ID', + type: 'string', + }).option('token', { + describe: 'Nintendo Account session token', + type: 'string', + }).option('json', { + describe: 'Output raw JSON', + type: 'boolean', + }).option('json-pretty-print', { + describe: 'Output pretty-printed JSON', + type: 'boolean', + }); +} + +type Arguments = YargsArguments>; + +export async function handler(argv: ArgumentsCamelCase) { + const storage = await initStorage(argv.dataPath); + + const usernsid = argv.user ?? await storage.getItem('SelectedUser'); + const token: string = argv.token || + await storage.getItem('NintendoAccountToken.' + usernsid); + const {nso, data} = await getToken(storage, token, argv.zncProxyUrl); + + const user = await nso.getUserByFriendCode(argv.id); + + if (argv.jsonPrettyPrint) { + console.log(JSON.stringify(user.result, null, 4)); + return; + } + if (argv.json) { + console.log(JSON.stringify(user.result)); + return; + } + + console.log('User', user.result); +}