Skip to content

Commit c3b238b

Browse files
committed
Add the rest of the OAuth providers
1 parent de1653f commit c3b238b

File tree

7 files changed

+441
-0
lines changed

7 files changed

+441
-0
lines changed

packages-exp/auth-exp/index.webworker.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,12 @@ export { inMemoryPersistence } from './src/core/persistence/in_memory';
5959

6060
// core/providers
6161
export { EmailAuthProvider } from './src/core/providers/email';
62+
export { FacebookAuthProvider } from './src/core/providers/facebook';
6263
export { GoogleAuthProvider } from './src/core/providers/google';
64+
export { GithubAuthProvider } from './src/core/providers/github';
6365
export { OAuthProvider } from './src/core/providers/oauth';
6466
export { PhoneAuthProvider } from './src/core/providers/phone';
67+
export { TwitterAuthProvider } from './src/core/providers/twitter';
6568

6669
// core/strategies
6770
export { signInAnonymously } from './src/core/strategies/anonymous';
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { expect } from 'chai';
19+
20+
import { OperationType, ProviderId, SignInMethod } from '@firebase/auth-types-exp';
21+
22+
import { TEST_ID_TOKEN_RESPONSE } from '../../../test/helpers/id_token_response';
23+
import { testUser } from '../../../test/helpers/mock_auth';
24+
import { TaggedWithTokenResponse } from '../../model/id_token';
25+
import { AUTH_ERROR_FACTORY, AuthErrorCode } from '../errors';
26+
import { UserCredentialImpl } from '../user/user_credential_impl';
27+
import { FacebookAuthProvider } from './facebook';
28+
29+
describe('src/core/providers/facebook', () => {
30+
it('generates the correct type of oauth credential', () => {
31+
const cred = FacebookAuthProvider.credential('access-token');
32+
expect(cred.accessToken).to.eq('access-token');
33+
expect(cred.providerId).to.eq(ProviderId.FACEBOOK);
34+
expect(cred.signInMethod).to.eq(SignInMethod.FACEBOOK);
35+
});
36+
37+
it('credentialFromResult creates the cred from a tagged result', () => {
38+
const userCred = new UserCredentialImpl({
39+
user: testUser({}, 'uid'),
40+
providerId: ProviderId.FACEBOOK,
41+
_tokenResponse: {
42+
...TEST_ID_TOKEN_RESPONSE,
43+
oauthAccessToken: 'access-token',
44+
},
45+
operationType: OperationType.SIGN_IN
46+
});
47+
const cred = FacebookAuthProvider.credentialFromResult(userCred)!;
48+
expect(cred.accessToken).to.eq('access-token');
49+
expect(cred.providerId).to.eq(ProviderId.FACEBOOK);
50+
expect(cred.signInMethod).to.eq(SignInMethod.FACEBOOK);
51+
});
52+
53+
it('credentialFromError creates the cred from a tagged error', () => {
54+
const error = AUTH_ERROR_FACTORY.create(AuthErrorCode.NEED_CONFIRMATION, {
55+
appName: 'foo'
56+
});
57+
(error as TaggedWithTokenResponse)._tokenResponse = {
58+
...TEST_ID_TOKEN_RESPONSE,
59+
oauthAccessToken: 'access-token',
60+
};
61+
62+
const cred = FacebookAuthProvider.credentialFromError(error)!;
63+
expect(cred.accessToken).to.eq('access-token');
64+
expect(cred.providerId).to.eq(ProviderId.FACEBOOK);
65+
expect(cred.signInMethod).to.eq(SignInMethod.FACEBOOK);
66+
});
67+
});
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import * as externs from '@firebase/auth-types-exp';
19+
import { FirebaseError } from '@firebase/util';
20+
21+
import { TaggedWithTokenResponse } from '../../model/id_token';
22+
import { UserCredential } from '../../model/user';
23+
import { OAuthCredential } from '../credentials/oauth';
24+
import { OAuthProvider } from './oauth';
25+
26+
export class FacebookAuthProvider extends OAuthProvider {
27+
static readonly FACEBOOK_SIGN_IN_METHOD = externs.SignInMethod.FACEBOOK;
28+
static readonly PROVIDER_ID = externs.ProviderId.FACEBOOK;
29+
readonly providerId = FacebookAuthProvider.PROVIDER_ID;
30+
31+
static credential(
32+
accessToken: string
33+
): externs.OAuthCredential {
34+
return OAuthCredential._fromParams({
35+
providerId: FacebookAuthProvider.PROVIDER_ID,
36+
signInMethod: FacebookAuthProvider.FACEBOOK_SIGN_IN_METHOD,
37+
accessToken
38+
});
39+
}
40+
41+
static credentialFromResult(
42+
userCredential: externs.UserCredential
43+
): externs.OAuthCredential | null {
44+
return FacebookAuthProvider.credentialFromTaggedObject(
45+
userCredential as UserCredential
46+
);
47+
}
48+
49+
static credentialFromError(
50+
error: FirebaseError
51+
): externs.OAuthCredential | null {
52+
return FacebookAuthProvider.credentialFromTaggedObject(
53+
error as TaggedWithTokenResponse
54+
);
55+
}
56+
57+
private static credentialFromTaggedObject({
58+
_tokenResponse: tokenResponse
59+
}: TaggedWithTokenResponse): externs.OAuthCredential | null {
60+
if (!tokenResponse || !('oauthAccessToken' in tokenResponse)) {
61+
return null;
62+
}
63+
64+
if (!tokenResponse.oauthAccessToken) {
65+
return null;
66+
}
67+
68+
try {
69+
return FacebookAuthProvider.credential(
70+
tokenResponse.oauthAccessToken
71+
);
72+
} catch {
73+
return null;
74+
}
75+
}
76+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { expect } from 'chai';
19+
20+
import { OperationType, ProviderId, SignInMethod } from '@firebase/auth-types-exp';
21+
22+
import { TEST_ID_TOKEN_RESPONSE } from '../../../test/helpers/id_token_response';
23+
import { testUser } from '../../../test/helpers/mock_auth';
24+
import { TaggedWithTokenResponse } from '../../model/id_token';
25+
import { AUTH_ERROR_FACTORY, AuthErrorCode } from '../errors';
26+
import { UserCredentialImpl } from '../user/user_credential_impl';
27+
import { GithubAuthProvider } from './github';
28+
29+
describe('src/core/providers/github', () => {
30+
it('generates the correct type of oauth credential', () => {
31+
const cred = GithubAuthProvider.credential('access-token');
32+
expect(cred.accessToken).to.eq('access-token');
33+
expect(cred.providerId).to.eq(ProviderId.GITHUB);
34+
expect(cred.signInMethod).to.eq(SignInMethod.GITHUB);
35+
});
36+
37+
it('credentialFromResult creates the cred from a tagged result', () => {
38+
const userCred = new UserCredentialImpl({
39+
user: testUser({}, 'uid'),
40+
providerId: ProviderId.GITHUB,
41+
_tokenResponse: {
42+
...TEST_ID_TOKEN_RESPONSE,
43+
oauthAccessToken: 'access-token',
44+
},
45+
operationType: OperationType.SIGN_IN
46+
});
47+
const cred = GithubAuthProvider.credentialFromResult(userCred)!;
48+
expect(cred.accessToken).to.eq('access-token');
49+
expect(cred.providerId).to.eq(ProviderId.GITHUB);
50+
expect(cred.signInMethod).to.eq(SignInMethod.GITHUB);
51+
});
52+
53+
it('credentialFromError creates the cred from a tagged error', () => {
54+
const error = AUTH_ERROR_FACTORY.create(AuthErrorCode.NEED_CONFIRMATION, {
55+
appName: 'foo'
56+
});
57+
(error as TaggedWithTokenResponse)._tokenResponse = {
58+
...TEST_ID_TOKEN_RESPONSE,
59+
oauthAccessToken: 'access-token',
60+
};
61+
62+
const cred = GithubAuthProvider.credentialFromError(error)!;
63+
expect(cred.accessToken).to.eq('access-token');
64+
expect(cred.providerId).to.eq(ProviderId.GITHUB);
65+
expect(cred.signInMethod).to.eq(SignInMethod.GITHUB);
66+
});
67+
});
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import * as externs from '@firebase/auth-types-exp';
19+
import { FirebaseError } from '@firebase/util';
20+
21+
import { TaggedWithTokenResponse } from '../../model/id_token';
22+
import { UserCredential } from '../../model/user';
23+
import { OAuthCredential } from '../credentials/oauth';
24+
import { OAuthProvider } from './oauth';
25+
26+
export class GithubAuthProvider extends OAuthProvider {
27+
static readonly GITHUB_SIGN_IN_METHOD = externs.SignInMethod.GITHUB;
28+
static readonly PROVIDER_ID = externs.ProviderId.GITHUB;
29+
readonly providerId = GithubAuthProvider.PROVIDER_ID;
30+
31+
static credential(
32+
accessToken: string
33+
): externs.OAuthCredential {
34+
return OAuthCredential._fromParams({
35+
providerId: GithubAuthProvider.PROVIDER_ID,
36+
signInMethod: GithubAuthProvider.GITHUB_SIGN_IN_METHOD,
37+
accessToken
38+
});
39+
}
40+
41+
static credentialFromResult(
42+
userCredential: externs.UserCredential
43+
): externs.OAuthCredential | null {
44+
return GithubAuthProvider.credentialFromTaggedObject(
45+
userCredential as UserCredential
46+
);
47+
}
48+
49+
static credentialFromError(
50+
error: FirebaseError
51+
): externs.OAuthCredential | null {
52+
return GithubAuthProvider.credentialFromTaggedObject(
53+
error as TaggedWithTokenResponse
54+
);
55+
}
56+
57+
private static credentialFromTaggedObject({
58+
_tokenResponse: tokenResponse
59+
}: TaggedWithTokenResponse): externs.OAuthCredential | null {
60+
if (!tokenResponse || !('oauthAccessToken' in tokenResponse)) {
61+
return null;
62+
}
63+
64+
if (!tokenResponse.oauthAccessToken) {
65+
return null;
66+
}
67+
68+
try {
69+
return GithubAuthProvider.credential(
70+
tokenResponse.oauthAccessToken
71+
);
72+
} catch {
73+
return null;
74+
}
75+
}
76+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Twitter LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import { expect } from 'chai';
19+
20+
import { OperationType, ProviderId, SignInMethod } from '@firebase/auth-types-exp';
21+
22+
import { TEST_ID_TOKEN_RESPONSE } from '../../../test/helpers/id_token_response';
23+
import { testUser } from '../../../test/helpers/mock_auth';
24+
import { TaggedWithTokenResponse } from '../../model/id_token';
25+
import { AUTH_ERROR_FACTORY, AuthErrorCode } from '../errors';
26+
import { UserCredentialImpl } from '../user/user_credential_impl';
27+
import { TwitterAuthProvider } from './twitter';
28+
29+
describe('src/core/providers/twitter', () => {
30+
it('generates the correct type of oauth credential', () => {
31+
const cred = TwitterAuthProvider.credential('token', 'secret');
32+
expect(cred.accessToken).to.eq('token');
33+
expect(cred.secret).to.eq('secret');
34+
expect(cred.providerId).to.eq(ProviderId.TWITTER);
35+
expect(cred.signInMethod).to.eq(SignInMethod.TWITTER);
36+
});
37+
38+
it('credentialFromResult creates the cred from a tagged result', () => {
39+
const userCred = new UserCredentialImpl({
40+
user: testUser({}, 'uid'),
41+
providerId: ProviderId.TWITTER,
42+
_tokenResponse: {
43+
...TEST_ID_TOKEN_RESPONSE,
44+
oauthAccessToken: 'access-token',
45+
oauthTokenSecret: 'token-secret'
46+
},
47+
operationType: OperationType.SIGN_IN
48+
});
49+
const cred = TwitterAuthProvider.credentialFromResult(userCred)!;
50+
expect(cred.accessToken).to.eq('access-token');
51+
expect(cred.secret).to.eq('token-secret');
52+
expect(cred.providerId).to.eq(ProviderId.TWITTER);
53+
expect(cred.signInMethod).to.eq(SignInMethod.TWITTER);
54+
});
55+
56+
it('credentialFromError creates the cred from a tagged error', () => {
57+
const error = AUTH_ERROR_FACTORY.create(AuthErrorCode.NEED_CONFIRMATION, {
58+
appName: 'foo'
59+
});
60+
(error as TaggedWithTokenResponse)._tokenResponse = {
61+
...TEST_ID_TOKEN_RESPONSE,
62+
oauthAccessToken: 'access-token',
63+
oauthTokenSecret: 'token-secret'
64+
};
65+
66+
const cred = TwitterAuthProvider.credentialFromError(error)!;
67+
expect(cred.accessToken).to.eq('access-token');
68+
expect(cred.secret).to.eq('token-secret');
69+
expect(cred.providerId).to.eq(ProviderId.TWITTER);
70+
expect(cred.signInMethod).to.eq(SignInMethod.TWITTER);
71+
});
72+
});

0 commit comments

Comments
 (0)