From ce6faebd0a564d9ebd1e9f3cd86c007faa8046e5 Mon Sep 17 00:00:00 2001
From: dblythy <daniel-blyth@live.com.au>
Date: Tue, 26 Apr 2022 22:54:23 +1000
Subject: [PATCH 1/4] feat: allow disabling of auth

---
 spec/ParseUser.spec.js | 15 +++++++++++++++
 src/RestWrite.js       |  3 ++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js
index 92301316e4..9462500538 100644
--- a/spec/ParseUser.spec.js
+++ b/spec/ParseUser.spec.js
@@ -1209,6 +1209,21 @@ describe('Parse.User testing', () => {
     done();
   });
 
+  it('can disable provider', async () => {
+    await reconfigureServer({
+      auth: {
+        facebook: {
+          enabled: false,
+        },
+      },
+    });
+    const provider = getMockFacebookProvider();
+    Parse.User._registerAuthenticationProvider(provider);
+    await expectAsync(Parse.User._logInWith('facebook')).toBeRejectedWith(
+      new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.')
+    );
+  });
+
   it('can not set authdata to null', async () => {
     try {
       const provider = getMockFacebookProvider();
diff --git a/src/RestWrite.js b/src/RestWrite.js
index 3e20328a9a..30c0f98f45 100644
--- a/src/RestWrite.js
+++ b/src/RestWrite.js
@@ -429,7 +429,8 @@ RestWrite.prototype.handleAuthDataValidation = function (authData) {
       return Promise.resolve();
     }
     const validateAuthData = this.config.authDataManager.getValidatorForProvider(provider);
-    if (!validateAuthData) {
+    const authProvider = (this.config.auth || {})[provider] || {};
+    if (!validateAuthData || authProvider.enabled === false) {
       throw new Parse.Error(
         Parse.Error.UNSUPPORTED_SERVICE,
         'This authentication method is unsupported.'

From 37b88a3abafcc270e34ab39ce20ec16394547a95 Mon Sep 17 00:00:00 2001
From: dblythy <daniel-blyth@live.com.au>
Date: Thu, 26 May 2022 08:37:10 +1000
Subject: [PATCH 2/4] add deprecator

---
 DEPRECATIONS.md                     |  1 +
 spec/AuthenticationAdapters.spec.js | 26 ++++++++++++++++++++++++++
 spec/ParseUser.spec.js              | 15 ---------------
 src/RestWrite.js                    |  7 +++++++
 4 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md
index 986522477b..e4ca0d41d9 100644
--- a/DEPRECATIONS.md
+++ b/DEPRECATIONS.md
@@ -9,6 +9,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h
 | DEPPS3 | Config option `enforcePrivateUsers` defaults to `true` | [#7319](https://github.com/parse-community/parse-server/pull/7319)   | 5.0.0 (2022)                    | 6.0.0 (2023)                    | deprecated            | -     |
 | DEPPS4 | Remove convenience method for http request `Parse.Cloud.httpRequest` | [#7589](https://github.com/parse-community/parse-server/pull/7589)   | 5.0.0 (2022)                    | 6.0.0 (2023)                    | deprecated            | -     |
 | DEPPS5 | Config option `allowClientClassCreation` defaults to `false` | [#7925](https://github.com/parse-community/parse-server/pull/7925)   | 5.3.0 (2022)                    | 7.0.0 (2024)                    | deprecated            | -     |
+| DEPPS6 | Auth providers disabled by default | [#7953](https://github.com/parse-community/parse-server/pull/7953)   | 5.3.0 (2022)                    | 7.0.0 (2024)                    | deprecated            | -     |
 
 [i_deprecation]: ## "The version and date of the deprecation."
 [i_removal]: ## "The version and date of the planned removal."
diff --git a/spec/AuthenticationAdapters.spec.js b/spec/AuthenticationAdapters.spec.js
index bfb64502cd..dff8b42258 100644
--- a/spec/AuthenticationAdapters.spec.js
+++ b/spec/AuthenticationAdapters.spec.js
@@ -477,6 +477,32 @@ describe('AuthenticationProviders', function () {
     expect(appIds).toEqual(['a', 'b']);
     expect(providerOptions).toEqual(options.custom);
   });
+
+  it('can disable provider', async () => {
+    await reconfigureServer({
+      auth: {
+        myoauth: {
+          enabled: false,
+          module: path.resolve(__dirname, 'support/myoauth'), // relative path as it's run from src
+        },
+      },
+    });
+    const provider = getMockMyOauthProvider();
+    Parse.User._registerAuthenticationProvider(provider);
+    await expectAsync(Parse.User._logInWith('myoauth')).toBeRejectedWith(
+      new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.')
+    );
+  });
+
+  it('can depreciate', async () => {
+    const Deprecator = require('../lib/Deprecator/Deprecator');
+    const spy = spyOn(Deprecator, 'logRuntimeDeprecation').and.callFake(() => {});
+    const provider = getMockMyOauthProvider();
+    Parse.User._registerAuthenticationProvider(provider);
+    await Parse.User._logInWith('myoauth');
+    expect(spy).toHaveBeenCalledWith({ usage: 'auth.myoauth', solution: 'auth.myoauth.enabled: true' });
+  });
+
 });
 
 describe('instagram auth adapter', () => {
diff --git a/spec/ParseUser.spec.js b/spec/ParseUser.spec.js
index 9462500538..92301316e4 100644
--- a/spec/ParseUser.spec.js
+++ b/spec/ParseUser.spec.js
@@ -1209,21 +1209,6 @@ describe('Parse.User testing', () => {
     done();
   });
 
-  it('can disable provider', async () => {
-    await reconfigureServer({
-      auth: {
-        facebook: {
-          enabled: false,
-        },
-      },
-    });
-    const provider = getMockFacebookProvider();
-    Parse.User._registerAuthenticationProvider(provider);
-    await expectAsync(Parse.User._logInWith('facebook')).toBeRejectedWith(
-      new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE, 'This authentication method is unsupported.')
-    );
-  });
-
   it('can not set authdata to null', async () => {
     try {
       const provider = getMockFacebookProvider();
diff --git a/src/RestWrite.js b/src/RestWrite.js
index 30c0f98f45..b25386a9af 100644
--- a/src/RestWrite.js
+++ b/src/RestWrite.js
@@ -15,6 +15,7 @@ var ClientSDK = require('./ClientSDK');
 import RestQuery from './RestQuery';
 import _ from 'lodash';
 import logger from './logger';
+import Deprecator from './Deprecator/Deprecator';
 
 // query and data are both provided in REST API format. So data
 // types are encoded by plain old objects.
@@ -430,6 +431,12 @@ RestWrite.prototype.handleAuthDataValidation = function (authData) {
     }
     const validateAuthData = this.config.authDataManager.getValidatorForProvider(provider);
     const authProvider = (this.config.auth || {})[provider] || {};
+    if (authProvider.enabled == null) {
+      Deprecator.logRuntimeDeprecation({
+        usage: `auth.${provider}`,
+        solution: `auth.${provider}.enabled: true`,
+      });
+    }
     if (!validateAuthData || authProvider.enabled === false) {
       throw new Parse.Error(
         Parse.Error.UNSUPPORTED_SERVICE,

From 14a63d273e037637f7c3ed5ba9ec1e734aed1563 Mon Sep 17 00:00:00 2001
From: dblythy <daniel-blyth@live.com.au>
Date: Fri, 27 May 2022 12:30:25 +1000
Subject: [PATCH 3/4] add auth docs

---
 src/Options/Definitions.js | 10 +++++++++-
 src/Options/docs.js        |  7 ++++++-
 src/Options/index.js       |  8 +++++++-
 3 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js
index f8b8eab633..a0f6a4de62 100644
--- a/src/Options/Definitions.js
+++ b/src/Options/Definitions.js
@@ -95,7 +95,7 @@ module.exports.ParseServerOptions = {
     env: 'PARSE_SERVER_AUTH_PROVIDERS',
     help:
       'Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication',
-    action: parsers.objectParser,
+    action: parsers.arrayParser,
   },
   cacheAdapter: {
     env: 'PARSE_SERVER_CACHE_ADAPTER',
@@ -876,3 +876,11 @@ module.exports.DatabaseOptions = {
     default: false,
   },
 };
+module.exports.AuthAdapter = {
+  enabled: {
+    env: 'undefinedENABLED',
+    help: 'Is `true` if the auth adapter is enabled, `false` otherwise.',
+    action: parsers.booleanParser,
+    default: true,
+  },
+};
diff --git a/src/Options/docs.js b/src/Options/docs.js
index 24b60c46a9..e8601bd4e5 100644
--- a/src/Options/docs.js
+++ b/src/Options/docs.js
@@ -19,7 +19,7 @@
  * @property {Adapter<AnalyticsAdapter>} analyticsAdapter Adapter module for the analytics
  * @property {String} appId Your Parse Application ID
  * @property {String} appName Sets the app name
- * @property {Any} auth Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication
+ * @property {AuthAdapter[]} auth Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication
  * @property {Adapter<CacheAdapter>} cacheAdapter Adapter module for the cache
  * @property {Number} cacheMaxSize Sets the maximum size for the in memory cache, defaults to 10000
  * @property {Number} cacheTTL Sets the TTL for the in memory cache (in ms), defaults to 5000 (5 seconds)
@@ -208,3 +208,8 @@
  * @interface DatabaseOptions
  * @property {Boolean} enableSchemaHooks Enables database real-time hooks to update single schema cache. Set to `true` if using multiple Parse Servers instances connected to the same database. Failing to do so will cause a schema change to not propagate to all instances and re-syncing will only happen when the instances restart. To use this feature with MongoDB, a replica set cluster with [change stream](https://docs.mongodb.com/manual/changeStreams/#availability) support is required.
  */
+
+/**
+ * @interface AuthAdapter
+ * @property {Boolean} enabled Is `true` if the auth adapter is enabled, `false` otherwise.
+ */
diff --git a/src/Options/index.js b/src/Options/index.js
index 8124446f99..9512baed2e 100644
--- a/src/Options/index.js
+++ b/src/Options/index.js
@@ -140,7 +140,7 @@ export interface ParseServerOptions {
   allowCustomObjectId: ?boolean;
   /* Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication
   :ENV: PARSE_SERVER_AUTH_PROVIDERS */
-  auth: ?any;
+  auth: ?(AuthAdapter[]);
   /* Max file size for uploads, defaults to 20mb
   :DEFAULT: 20mb */
   maxUploadSize: ?string;
@@ -506,3 +506,9 @@ export interface DatabaseOptions {
   :DEFAULT: false */
   enableSchemaHooks: ?boolean;
 }
+
+export interface AuthAdapter {
+  /* Is `true` if the auth adapter is enabled, `false` otherwise.
+  :DEFAULT: true */
+  enabled: ?boolean;
+}

From 15b5af57d8a3c1da233de50218292cac5d1b7f2e Mon Sep 17 00:00:00 2001
From: dblythy <daniel-blyth@live.com.au>
Date: Sat, 28 May 2022 17:11:12 +1000
Subject: [PATCH 4/4] remove env option

---
 src/Options/Definitions.js | 1 -
 src/Options/index.js       | 4 +++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js
index a0f6a4de62..c9a316db36 100644
--- a/src/Options/Definitions.js
+++ b/src/Options/Definitions.js
@@ -878,7 +878,6 @@ module.exports.DatabaseOptions = {
 };
 module.exports.AuthAdapter = {
   enabled: {
-    env: 'undefinedENABLED',
     help: 'Is `true` if the auth adapter is enabled, `false` otherwise.',
     action: parsers.booleanParser,
     default: true,
diff --git a/src/Options/index.js b/src/Options/index.js
index 9512baed2e..c298bc78e2 100644
--- a/src/Options/index.js
+++ b/src/Options/index.js
@@ -509,6 +509,8 @@ export interface DatabaseOptions {
 
 export interface AuthAdapter {
   /* Is `true` if the auth adapter is enabled, `false` otherwise.
-  :DEFAULT: true */
+  :DEFAULT: true
+  :ENV:
+  */
   enabled: ?boolean;
 }