Use Nintendo Switch client ID

Reputable projects such as prismarine-auth and azalea-auth hardcode the
Nintendo Switch client ID instead of their own custom Azure application,
so we should be fine to go ahead and do the same.

Unfortunately, client IDs created for custom Azure applications, such as
Prism Launcher's client ID, will no longer work with Fjord Launcher, so
users who manually supplied a client ID will need to clear theirs.
This commit is contained in:
Evan Goode 2024-05-20 13:14:39 -04:00
parent 51da756e19
commit 62f87c423f
6 changed files with 14 additions and 17 deletions

View File

@ -232,15 +232,8 @@ elseif(WIN32)
endif() endif()
# API Keys # API Keys
# NOTE: These API keys are here for convenience. If you rebrand this software or intend to break the terms of service # Nintendo Switch Client ID, used by prismarine-auth and azalea-auth.
# of these platforms, please change these API keys beforehand. set(Launcher_MSA_CLIENT_ID "00000000441cc96b" CACHE STRING "Microsoft auth title. Not compatible with Prism Launcher (Azure) client IDs.")
# Be aware that if you were to use these API keys for malicious purposes they might get revoked, which might cause
# breakage to thousands of users.
# If you don't plan to use these features of this software, you can just remove these values.
# By using this key in your builds you accept the terms of use laid down in
# https://docs.microsoft.com/en-us/legal/microsoft-identity-platform/terms-of-use
set(Launcher_MSA_CLIENT_ID "" CACHE STRING "Client ID you can get from Microsoft Identity Platform when you register an application")
# By using this key in your builds you accept the terms and conditions laid down in # By using this key in your builds you accept the terms and conditions laid down in
# https://support.curseforge.com/en/support/solutions/articles/9000207405-curse-forge-3rd-party-api-terms-and-conditions # https://support.curseforge.com/en/support/solutions/articles/9000207405-curse-forge-3rd-party-api-terms-and-conditions

View File

@ -405,7 +405,7 @@ void LaunchController::launchInstance()
online_mode = "online"; online_mode = "online";
// Prepend Server Status // Prepend Server Status
QStringList servers = { "login.microsoftonline.com", "session.minecraft.net", "textures.minecraft.net", "api.mojang.com" }; QStringList servers = { "login.live.com", "session.minecraft.net", "textures.minecraft.net", "api.mojang.com" };
QString resolved_servers = ""; QString resolved_servers = "";
QHostInfo host_info; QHostInfo host_info;

View File

@ -51,10 +51,11 @@ MSAStep::MSAStep(AccountData* data, Action action) : AuthStep(data), m_action(ac
{ {
m_clientId = APPLICATION->getMSAClientID(); m_clientId = APPLICATION->getMSAClientID();
OAuth2::Options opts; OAuth2::Options opts;
opts.scope = "XboxLive.signin offline_access"; opts.scope = "service::user.auth.xboxlive.com::MBI_SSL";
opts.clientIdentifier = m_clientId; opts.clientIdentifier = m_clientId;
opts.authorizationUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode"; opts.authorizationUrl = "https://login.live.com/oauth20_connect.srf";
opts.accessTokenUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token"; opts.accessTokenUrl = "https://login.live.com/oauth20_token.srf";
opts.responseType = "device_code";
// FIXME: OAuth2 is not aware of our fancy shared pointers // FIXME: OAuth2 is not aware of our fancy shared pointers
m_oauth2 = new OAuth2(opts, m_data->msaToken, this, APPLICATION->network().get()); m_oauth2 = new OAuth2(opts, m_data->msaToken, this, APPLICATION->network().get());

View File

@ -27,7 +27,7 @@ void XboxUserStep::perform()
"Properties": { "Properties": {
"AuthMethod": "RPS", "AuthMethod": "RPS",
"SiteName": "user.auth.xboxlive.com", "SiteName": "user.auth.xboxlive.com",
"RpsTicket": "d=%1" "RpsTicket": "%1"
}, },
"RelyingParty": "http://auth.xboxlive.com", "RelyingParty": "http://auth.xboxlive.com",
"TokenType": "JWT" "TokenType": "JWT"

View File

@ -61,8 +61,7 @@ APIPage::APIPage(QWidget* parent) : QWidget(parent), ui(new Ui::APIPage)
PasteUpload::PasteType::Hastebin }; PasteUpload::PasteType::Hastebin };
static QRegularExpression validUrlRegExp("https?://.+"); static QRegularExpression validUrlRegExp("https?://.+");
static QRegularExpression validMSAClientID( static QRegularExpression validMSAClientID(QRegularExpression::anchoredPattern(".+"));
QRegularExpression::anchoredPattern("[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}"));
static QRegularExpression validFlameKey(QRegularExpression::anchoredPattern("\\$2[ayb]\\$.{56}")); static QRegularExpression validFlameKey(QRegularExpression::anchoredPattern("\\$2[ayb]\\$.{56}"));
ui->setupUi(this); ui->setupUi(this);

View File

@ -177,6 +177,7 @@ void DeviceFlow::login()
QList<RequestParameter> parameters; QList<RequestParameter> parameters;
parameters.append(RequestParameter(OAUTH2_CLIENT_ID, options_.clientIdentifier.toUtf8())); parameters.append(RequestParameter(OAUTH2_CLIENT_ID, options_.clientIdentifier.toUtf8()));
parameters.append(RequestParameter(OAUTH2_SCOPE, options_.scope.toUtf8())); parameters.append(RequestParameter(OAUTH2_SCOPE, options_.scope.toUtf8()));
parameters.append(RequestParameter(OAUTH2_RESPONSE_TYPE, options_.responseType.toUtf8()));
QByteArray payload = createQueryParameters(parameters); QByteArray payload = createQueryParameters(parameters);
QUrl url(options_.authorizationUrl); QUrl url(options_.authorizationUrl);
@ -261,8 +262,10 @@ void DeviceFlow::startPollServer(const QVariantMap& params, int expiresIn)
if (!options_.clientSecret.isEmpty()) { if (!options_.clientSecret.isEmpty()) {
parameters.append(RequestParameter(OAUTH2_CLIENT_SECRET, options_.clientSecret.toUtf8())); parameters.append(RequestParameter(OAUTH2_CLIENT_SECRET, options_.clientSecret.toUtf8()));
} }
parameters.append(RequestParameter(OAUTH2_CODE, deviceCode.toUtf8())); parameters.append(RequestParameter(OAUTH2_DEVICE_CODE, deviceCode.toUtf8()));
parameters.append(RequestParameter(OAUTH2_GRANT_TYPE, grantType.toUtf8())); parameters.append(RequestParameter(OAUTH2_GRANT_TYPE, grantType.toUtf8()));
parameters.append(RequestParameter(OAUTH2_RESPONSE_TYPE, options_.responseType.toUtf8()));
QByteArray payload = createQueryParameters(parameters); QByteArray payload = createQueryParameters(parameters);
PollServer* pollServer = new PollServer(manager_, authRequest, payload, expiresIn, this); PollServer* pollServer = new PollServer(manager_, authRequest, payload, expiresIn, this);
@ -395,6 +398,7 @@ bool DeviceFlow::refresh()
if (!options_.clientSecret.isEmpty()) { if (!options_.clientSecret.isEmpty()) {
parameters.insert(OAUTH2_CLIENT_SECRET, options_.clientSecret); parameters.insert(OAUTH2_CLIENT_SECRET, options_.clientSecret);
} }
parameters.insert(OAUTH2_SCOPE, options_.scope.toUtf8());
parameters.insert(OAUTH2_REFRESH_TOKEN, refreshToken()); parameters.insert(OAUTH2_REFRESH_TOKEN, refreshToken());
parameters.insert(OAUTH2_GRANT_TYPE, OAUTH2_REFRESH_TOKEN); parameters.insert(OAUTH2_GRANT_TYPE, OAUTH2_REFRESH_TOKEN);