@capawesome/capacitor-apple-sign-in 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CapawesomeCapacitorAppleSignIn.podspec +17 -0
- package/Package.swift +28 -0
- package/README.md +220 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +9 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/applesignin/AppleSignIn.java +98 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/applesignin/AppleSignInActivity.java +366 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/applesignin/AppleSignInPlugin.java +106 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/applesignin/classes/CustomException.java +20 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/applesignin/classes/CustomExceptions.java +12 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/applesignin/classes/options/SignInOptions.java +84 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/applesignin/classes/results/SignInResult.java +65 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/applesignin/interfaces/Callback.java +5 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/applesignin/interfaces/NonEmptyResultCallback.java +7 -0
- package/android/src/main/java/io/capawesome/capacitorjs/plugins/applesignin/interfaces/Result.java +7 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/android/src/main/res/drawable/ic_close.xml +9 -0
- package/dist/docs.json +345 -0
- package/dist/esm/definitions.d.ts +181 -0
- package/dist/esm/definitions.js +55 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +10 -0
- package/dist/esm/web.js +79 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +148 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +151 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/AppleSignIn.swift +48 -0
- package/ios/Plugin/AppleSignInPlugin.swift +67 -0
- package/ios/Plugin/Classes/Options/SignInOptions.swift +31 -0
- package/ios/Plugin/Classes/Results/SignInResult.swift +46 -0
- package/ios/Plugin/Enums/CustomError.swift +26 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/Protocols/Result.swift +6 -0
- package/package.json +93 -0
package/dist/esm/web.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
export class AppleSignInWeb extends WebPlugin {
|
|
3
|
+
constructor() {
|
|
4
|
+
super(...arguments);
|
|
5
|
+
this.scriptLoaded = false;
|
|
6
|
+
}
|
|
7
|
+
async initialize(options) {
|
|
8
|
+
this.clientId = options.clientId;
|
|
9
|
+
await this.loadScript();
|
|
10
|
+
}
|
|
11
|
+
async signIn(options) {
|
|
12
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
13
|
+
if (!this.clientId) {
|
|
14
|
+
throw new Error('clientId must be provided. Call initialize() first.');
|
|
15
|
+
}
|
|
16
|
+
const scope = ((_a = options === null || options === void 0 ? void 0 : options.scopes) !== null && _a !== void 0 ? _a : [])
|
|
17
|
+
.map(s => (s === 'FULL_NAME' ? 'name' : 'email'))
|
|
18
|
+
.join(' ');
|
|
19
|
+
window.AppleID.auth.init({
|
|
20
|
+
clientId: this.clientId,
|
|
21
|
+
scope: scope || undefined,
|
|
22
|
+
redirectURI: options === null || options === void 0 ? void 0 : options.redirectUrl,
|
|
23
|
+
state: options === null || options === void 0 ? void 0 : options.state,
|
|
24
|
+
nonce: options === null || options === void 0 ? void 0 : options.nonce,
|
|
25
|
+
usePopup: true,
|
|
26
|
+
});
|
|
27
|
+
const response = await window.AppleID.auth.signIn();
|
|
28
|
+
const authorization = response.authorization;
|
|
29
|
+
const idToken = authorization.id_token;
|
|
30
|
+
const authorizationCode = authorization.code;
|
|
31
|
+
const state = authorization.state;
|
|
32
|
+
const payload = this.decodeJwtPayload(idToken);
|
|
33
|
+
const user = payload.sub;
|
|
34
|
+
const email = (_b = payload.email) !== null && _b !== void 0 ? _b : null;
|
|
35
|
+
let givenName = null;
|
|
36
|
+
let familyName = null;
|
|
37
|
+
if (response.user) {
|
|
38
|
+
givenName = (_d = (_c = response.user.name) === null || _c === void 0 ? void 0 : _c.firstName) !== null && _d !== void 0 ? _d : null;
|
|
39
|
+
familyName = (_f = (_e = response.user.name) === null || _e === void 0 ? void 0 : _e.lastName) !== null && _f !== void 0 ? _f : null;
|
|
40
|
+
}
|
|
41
|
+
const result = {
|
|
42
|
+
authorizationCode,
|
|
43
|
+
idToken,
|
|
44
|
+
user,
|
|
45
|
+
email: (_h = (_g = response.user) === null || _g === void 0 ? void 0 : _g.email) !== null && _h !== void 0 ? _h : email,
|
|
46
|
+
givenName,
|
|
47
|
+
familyName,
|
|
48
|
+
};
|
|
49
|
+
if (state !== undefined) {
|
|
50
|
+
result.state = state;
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
decodeJwtPayload(jwt) {
|
|
55
|
+
const parts = jwt.split('.');
|
|
56
|
+
const payload = parts[1];
|
|
57
|
+
const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
|
|
58
|
+
return JSON.parse(decoded);
|
|
59
|
+
}
|
|
60
|
+
loadScript() {
|
|
61
|
+
if (this.scriptLoaded) {
|
|
62
|
+
return Promise.resolve();
|
|
63
|
+
}
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
const script = document.createElement('script');
|
|
66
|
+
script.src =
|
|
67
|
+
'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';
|
|
68
|
+
script.onload = () => {
|
|
69
|
+
this.scriptLoaded = true;
|
|
70
|
+
resolve();
|
|
71
|
+
};
|
|
72
|
+
script.onerror = () => {
|
|
73
|
+
reject(new Error('Failed to load Apple Sign-In SDK.'));
|
|
74
|
+
};
|
|
75
|
+
document.head.appendChild(script);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"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","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type {\n AppleSignInPlugin,\n InitializeOptions,\n SignInOptions,\n SignInResult,\n} from './definitions';\n\nexport class AppleSignInWeb extends WebPlugin implements AppleSignInPlugin {\n private clientId: string | undefined;\n private scriptLoaded = false;\n\n async initialize(options: InitializeOptions): Promise<void> {\n this.clientId = options.clientId;\n await this.loadScript();\n }\n\n async signIn(options?: SignInOptions): Promise<SignInResult> {\n if (!this.clientId) {\n throw new Error('clientId must be provided. Call initialize() first.');\n }\n\n const scope = (options?.scopes ?? [])\n .map(s => (s === 'FULL_NAME' ? 'name' : 'email'))\n .join(' ');\n\n (window as any).AppleID.auth.init({\n clientId: this.clientId,\n scope: scope || undefined,\n redirectURI: options?.redirectUrl,\n state: options?.state,\n nonce: options?.nonce,\n usePopup: true,\n });\n\n const response = await (window as any).AppleID.auth.signIn();\n\n const authorization = response.authorization;\n const idToken: string = authorization.id_token;\n const authorizationCode: string = authorization.code;\n const state: string | undefined = authorization.state;\n\n const payload = this.decodeJwtPayload(idToken);\n const user: string = payload.sub;\n const email: string | null = payload.email ?? null;\n\n let givenName: string | null = null;\n let familyName: string | null = null;\n if (response.user) {\n givenName = response.user.name?.firstName ?? null;\n familyName = response.user.name?.lastName ?? null;\n }\n\n const result: SignInResult = {\n authorizationCode,\n idToken,\n user,\n email: response.user?.email ?? email,\n givenName,\n familyName,\n };\n if (state !== undefined) {\n result.state = state;\n }\n return result;\n }\n\n private decodeJwtPayload(jwt: string): any {\n const parts = jwt.split('.');\n const payload = parts[1];\n const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));\n return JSON.parse(decoded);\n }\n\n private loadScript(): Promise<void> {\n if (this.scriptLoaded) {\n return Promise.resolve();\n }\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src =\n 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';\n script.onload = () => {\n this.scriptLoaded = true;\n resolve();\n };\n script.onerror = () => {\n reject(new Error('Failed to load Apple Sign-In SDK.'));\n };\n document.head.appendChild(script);\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@capacitor/core');
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @since 0.1.0
|
|
7
|
+
*/
|
|
8
|
+
exports.SignInScope = void 0;
|
|
9
|
+
(function (SignInScope) {
|
|
10
|
+
/**
|
|
11
|
+
* Request the user's email address.
|
|
12
|
+
*
|
|
13
|
+
* @since 0.1.0
|
|
14
|
+
*/
|
|
15
|
+
SignInScope["Email"] = "EMAIL";
|
|
16
|
+
/**
|
|
17
|
+
* Request the user's full name.
|
|
18
|
+
*
|
|
19
|
+
* @since 0.1.0
|
|
20
|
+
*/
|
|
21
|
+
SignInScope["FullName"] = "FULL_NAME";
|
|
22
|
+
})(exports.SignInScope || (exports.SignInScope = {}));
|
|
23
|
+
/**
|
|
24
|
+
* @since 0.1.0
|
|
25
|
+
*/
|
|
26
|
+
exports.RealUserStatus = void 0;
|
|
27
|
+
(function (RealUserStatus) {
|
|
28
|
+
/**
|
|
29
|
+
* The user appears to be a real person.
|
|
30
|
+
*
|
|
31
|
+
* @since 0.1.0
|
|
32
|
+
*/
|
|
33
|
+
RealUserStatus["LikelyReal"] = "LIKELY_REAL";
|
|
34
|
+
/**
|
|
35
|
+
* The system can't determine whether the user is a real person.
|
|
36
|
+
*
|
|
37
|
+
* @since 0.1.0
|
|
38
|
+
*/
|
|
39
|
+
RealUserStatus["Unknown"] = "UNKNOWN";
|
|
40
|
+
/**
|
|
41
|
+
* The real user status is not supported on this platform.
|
|
42
|
+
*
|
|
43
|
+
* @since 0.1.0
|
|
44
|
+
*/
|
|
45
|
+
RealUserStatus["Unsupported"] = "UNSUPPORTED";
|
|
46
|
+
})(exports.RealUserStatus || (exports.RealUserStatus = {}));
|
|
47
|
+
/**
|
|
48
|
+
* @since 0.1.0
|
|
49
|
+
*/
|
|
50
|
+
exports.ErrorCode = void 0;
|
|
51
|
+
(function (ErrorCode) {
|
|
52
|
+
/**
|
|
53
|
+
* The sign-in was canceled by the user.
|
|
54
|
+
*
|
|
55
|
+
* @since 0.1.0
|
|
56
|
+
*/
|
|
57
|
+
ErrorCode["SignInCanceled"] = "SIGN_IN_CANCELED";
|
|
58
|
+
})(exports.ErrorCode || (exports.ErrorCode = {}));
|
|
59
|
+
|
|
60
|
+
const AppleSignIn = core.registerPlugin('AppleSignIn', {
|
|
61
|
+
web: () => Promise.resolve().then(function () { return web; }).then(m => new m.AppleSignInWeb()),
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
class AppleSignInWeb extends core.WebPlugin {
|
|
65
|
+
constructor() {
|
|
66
|
+
super(...arguments);
|
|
67
|
+
this.scriptLoaded = false;
|
|
68
|
+
}
|
|
69
|
+
async initialize(options) {
|
|
70
|
+
this.clientId = options.clientId;
|
|
71
|
+
await this.loadScript();
|
|
72
|
+
}
|
|
73
|
+
async signIn(options) {
|
|
74
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
75
|
+
if (!this.clientId) {
|
|
76
|
+
throw new Error('clientId must be provided. Call initialize() first.');
|
|
77
|
+
}
|
|
78
|
+
const scope = ((_a = options === null || options === void 0 ? void 0 : options.scopes) !== null && _a !== void 0 ? _a : [])
|
|
79
|
+
.map(s => (s === 'FULL_NAME' ? 'name' : 'email'))
|
|
80
|
+
.join(' ');
|
|
81
|
+
window.AppleID.auth.init({
|
|
82
|
+
clientId: this.clientId,
|
|
83
|
+
scope: scope || undefined,
|
|
84
|
+
redirectURI: options === null || options === void 0 ? void 0 : options.redirectUrl,
|
|
85
|
+
state: options === null || options === void 0 ? void 0 : options.state,
|
|
86
|
+
nonce: options === null || options === void 0 ? void 0 : options.nonce,
|
|
87
|
+
usePopup: true,
|
|
88
|
+
});
|
|
89
|
+
const response = await window.AppleID.auth.signIn();
|
|
90
|
+
const authorization = response.authorization;
|
|
91
|
+
const idToken = authorization.id_token;
|
|
92
|
+
const authorizationCode = authorization.code;
|
|
93
|
+
const state = authorization.state;
|
|
94
|
+
const payload = this.decodeJwtPayload(idToken);
|
|
95
|
+
const user = payload.sub;
|
|
96
|
+
const email = (_b = payload.email) !== null && _b !== void 0 ? _b : null;
|
|
97
|
+
let givenName = null;
|
|
98
|
+
let familyName = null;
|
|
99
|
+
if (response.user) {
|
|
100
|
+
givenName = (_d = (_c = response.user.name) === null || _c === void 0 ? void 0 : _c.firstName) !== null && _d !== void 0 ? _d : null;
|
|
101
|
+
familyName = (_f = (_e = response.user.name) === null || _e === void 0 ? void 0 : _e.lastName) !== null && _f !== void 0 ? _f : null;
|
|
102
|
+
}
|
|
103
|
+
const result = {
|
|
104
|
+
authorizationCode,
|
|
105
|
+
idToken,
|
|
106
|
+
user,
|
|
107
|
+
email: (_h = (_g = response.user) === null || _g === void 0 ? void 0 : _g.email) !== null && _h !== void 0 ? _h : email,
|
|
108
|
+
givenName,
|
|
109
|
+
familyName,
|
|
110
|
+
};
|
|
111
|
+
if (state !== undefined) {
|
|
112
|
+
result.state = state;
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
decodeJwtPayload(jwt) {
|
|
117
|
+
const parts = jwt.split('.');
|
|
118
|
+
const payload = parts[1];
|
|
119
|
+
const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
|
|
120
|
+
return JSON.parse(decoded);
|
|
121
|
+
}
|
|
122
|
+
loadScript() {
|
|
123
|
+
if (this.scriptLoaded) {
|
|
124
|
+
return Promise.resolve();
|
|
125
|
+
}
|
|
126
|
+
return new Promise((resolve, reject) => {
|
|
127
|
+
const script = document.createElement('script');
|
|
128
|
+
script.src =
|
|
129
|
+
'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';
|
|
130
|
+
script.onload = () => {
|
|
131
|
+
this.scriptLoaded = true;
|
|
132
|
+
resolve();
|
|
133
|
+
};
|
|
134
|
+
script.onerror = () => {
|
|
135
|
+
reject(new Error('Failed to load Apple Sign-In SDK.'));
|
|
136
|
+
};
|
|
137
|
+
document.head.appendChild(script);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
143
|
+
__proto__: null,
|
|
144
|
+
AppleSignInWeb: AppleSignInWeb
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
exports.AppleSignIn = AppleSignIn;
|
|
148
|
+
//# sourceMappingURL=plugin.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["esm/definitions.js","esm/index.js","esm/web.js"],"sourcesContent":["/**\n * @since 0.1.0\n */\nexport var SignInScope;\n(function (SignInScope) {\n /**\n * Request the user's email address.\n *\n * @since 0.1.0\n */\n SignInScope[\"Email\"] = \"EMAIL\";\n /**\n * Request the user's full name.\n *\n * @since 0.1.0\n */\n SignInScope[\"FullName\"] = \"FULL_NAME\";\n})(SignInScope || (SignInScope = {}));\n/**\n * @since 0.1.0\n */\nexport var RealUserStatus;\n(function (RealUserStatus) {\n /**\n * The user appears to be a real person.\n *\n * @since 0.1.0\n */\n RealUserStatus[\"LikelyReal\"] = \"LIKELY_REAL\";\n /**\n * The system can't determine whether the user is a real person.\n *\n * @since 0.1.0\n */\n RealUserStatus[\"Unknown\"] = \"UNKNOWN\";\n /**\n * The real user status is not supported on this platform.\n *\n * @since 0.1.0\n */\n RealUserStatus[\"Unsupported\"] = \"UNSUPPORTED\";\n})(RealUserStatus || (RealUserStatus = {}));\n/**\n * @since 0.1.0\n */\nexport var ErrorCode;\n(function (ErrorCode) {\n /**\n * The sign-in was canceled by the user.\n *\n * @since 0.1.0\n */\n ErrorCode[\"SignInCanceled\"] = \"SIGN_IN_CANCELED\";\n})(ErrorCode || (ErrorCode = {}));\n//# sourceMappingURL=definitions.js.map","import { registerPlugin } from '@capacitor/core';\nconst AppleSignIn = registerPlugin('AppleSignIn', {\n web: () => import('./web').then(m => new m.AppleSignInWeb()),\n});\nexport * from './definitions';\nexport { AppleSignIn };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class AppleSignInWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.scriptLoaded = false;\n }\n async initialize(options) {\n this.clientId = options.clientId;\n await this.loadScript();\n }\n async signIn(options) {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n if (!this.clientId) {\n throw new Error('clientId must be provided. Call initialize() first.');\n }\n const scope = ((_a = options === null || options === void 0 ? void 0 : options.scopes) !== null && _a !== void 0 ? _a : [])\n .map(s => (s === 'FULL_NAME' ? 'name' : 'email'))\n .join(' ');\n window.AppleID.auth.init({\n clientId: this.clientId,\n scope: scope || undefined,\n redirectURI: options === null || options === void 0 ? void 0 : options.redirectUrl,\n state: options === null || options === void 0 ? void 0 : options.state,\n nonce: options === null || options === void 0 ? void 0 : options.nonce,\n usePopup: true,\n });\n const response = await window.AppleID.auth.signIn();\n const authorization = response.authorization;\n const idToken = authorization.id_token;\n const authorizationCode = authorization.code;\n const state = authorization.state;\n const payload = this.decodeJwtPayload(idToken);\n const user = payload.sub;\n const email = (_b = payload.email) !== null && _b !== void 0 ? _b : null;\n let givenName = null;\n let familyName = null;\n if (response.user) {\n givenName = (_d = (_c = response.user.name) === null || _c === void 0 ? void 0 : _c.firstName) !== null && _d !== void 0 ? _d : null;\n familyName = (_f = (_e = response.user.name) === null || _e === void 0 ? void 0 : _e.lastName) !== null && _f !== void 0 ? _f : null;\n }\n const result = {\n authorizationCode,\n idToken,\n user,\n email: (_h = (_g = response.user) === null || _g === void 0 ? void 0 : _g.email) !== null && _h !== void 0 ? _h : email,\n givenName,\n familyName,\n };\n if (state !== undefined) {\n result.state = state;\n }\n return result;\n }\n decodeJwtPayload(jwt) {\n const parts = jwt.split('.');\n const payload = parts[1];\n const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));\n return JSON.parse(decoded);\n }\n loadScript() {\n if (this.scriptLoaded) {\n return Promise.resolve();\n }\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src =\n 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';\n script.onload = () => {\n this.scriptLoaded = true;\n resolve();\n };\n script.onerror = () => {\n reject(new Error('Failed to load Apple Sign-In SDK.'));\n };\n document.head.appendChild(script);\n });\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["SignInScope","RealUserStatus","ErrorCode","registerPlugin","WebPlugin"],"mappings":"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"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
var capacitorAppleSignIn = (function (exports, core) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @since 0.1.0
|
|
6
|
+
*/
|
|
7
|
+
exports.SignInScope = void 0;
|
|
8
|
+
(function (SignInScope) {
|
|
9
|
+
/**
|
|
10
|
+
* Request the user's email address.
|
|
11
|
+
*
|
|
12
|
+
* @since 0.1.0
|
|
13
|
+
*/
|
|
14
|
+
SignInScope["Email"] = "EMAIL";
|
|
15
|
+
/**
|
|
16
|
+
* Request the user's full name.
|
|
17
|
+
*
|
|
18
|
+
* @since 0.1.0
|
|
19
|
+
*/
|
|
20
|
+
SignInScope["FullName"] = "FULL_NAME";
|
|
21
|
+
})(exports.SignInScope || (exports.SignInScope = {}));
|
|
22
|
+
/**
|
|
23
|
+
* @since 0.1.0
|
|
24
|
+
*/
|
|
25
|
+
exports.RealUserStatus = void 0;
|
|
26
|
+
(function (RealUserStatus) {
|
|
27
|
+
/**
|
|
28
|
+
* The user appears to be a real person.
|
|
29
|
+
*
|
|
30
|
+
* @since 0.1.0
|
|
31
|
+
*/
|
|
32
|
+
RealUserStatus["LikelyReal"] = "LIKELY_REAL";
|
|
33
|
+
/**
|
|
34
|
+
* The system can't determine whether the user is a real person.
|
|
35
|
+
*
|
|
36
|
+
* @since 0.1.0
|
|
37
|
+
*/
|
|
38
|
+
RealUserStatus["Unknown"] = "UNKNOWN";
|
|
39
|
+
/**
|
|
40
|
+
* The real user status is not supported on this platform.
|
|
41
|
+
*
|
|
42
|
+
* @since 0.1.0
|
|
43
|
+
*/
|
|
44
|
+
RealUserStatus["Unsupported"] = "UNSUPPORTED";
|
|
45
|
+
})(exports.RealUserStatus || (exports.RealUserStatus = {}));
|
|
46
|
+
/**
|
|
47
|
+
* @since 0.1.0
|
|
48
|
+
*/
|
|
49
|
+
exports.ErrorCode = void 0;
|
|
50
|
+
(function (ErrorCode) {
|
|
51
|
+
/**
|
|
52
|
+
* The sign-in was canceled by the user.
|
|
53
|
+
*
|
|
54
|
+
* @since 0.1.0
|
|
55
|
+
*/
|
|
56
|
+
ErrorCode["SignInCanceled"] = "SIGN_IN_CANCELED";
|
|
57
|
+
})(exports.ErrorCode || (exports.ErrorCode = {}));
|
|
58
|
+
|
|
59
|
+
const AppleSignIn = core.registerPlugin('AppleSignIn', {
|
|
60
|
+
web: () => Promise.resolve().then(function () { return web; }).then(m => new m.AppleSignInWeb()),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
class AppleSignInWeb extends core.WebPlugin {
|
|
64
|
+
constructor() {
|
|
65
|
+
super(...arguments);
|
|
66
|
+
this.scriptLoaded = false;
|
|
67
|
+
}
|
|
68
|
+
async initialize(options) {
|
|
69
|
+
this.clientId = options.clientId;
|
|
70
|
+
await this.loadScript();
|
|
71
|
+
}
|
|
72
|
+
async signIn(options) {
|
|
73
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
74
|
+
if (!this.clientId) {
|
|
75
|
+
throw new Error('clientId must be provided. Call initialize() first.');
|
|
76
|
+
}
|
|
77
|
+
const scope = ((_a = options === null || options === void 0 ? void 0 : options.scopes) !== null && _a !== void 0 ? _a : [])
|
|
78
|
+
.map(s => (s === 'FULL_NAME' ? 'name' : 'email'))
|
|
79
|
+
.join(' ');
|
|
80
|
+
window.AppleID.auth.init({
|
|
81
|
+
clientId: this.clientId,
|
|
82
|
+
scope: scope || undefined,
|
|
83
|
+
redirectURI: options === null || options === void 0 ? void 0 : options.redirectUrl,
|
|
84
|
+
state: options === null || options === void 0 ? void 0 : options.state,
|
|
85
|
+
nonce: options === null || options === void 0 ? void 0 : options.nonce,
|
|
86
|
+
usePopup: true,
|
|
87
|
+
});
|
|
88
|
+
const response = await window.AppleID.auth.signIn();
|
|
89
|
+
const authorization = response.authorization;
|
|
90
|
+
const idToken = authorization.id_token;
|
|
91
|
+
const authorizationCode = authorization.code;
|
|
92
|
+
const state = authorization.state;
|
|
93
|
+
const payload = this.decodeJwtPayload(idToken);
|
|
94
|
+
const user = payload.sub;
|
|
95
|
+
const email = (_b = payload.email) !== null && _b !== void 0 ? _b : null;
|
|
96
|
+
let givenName = null;
|
|
97
|
+
let familyName = null;
|
|
98
|
+
if (response.user) {
|
|
99
|
+
givenName = (_d = (_c = response.user.name) === null || _c === void 0 ? void 0 : _c.firstName) !== null && _d !== void 0 ? _d : null;
|
|
100
|
+
familyName = (_f = (_e = response.user.name) === null || _e === void 0 ? void 0 : _e.lastName) !== null && _f !== void 0 ? _f : null;
|
|
101
|
+
}
|
|
102
|
+
const result = {
|
|
103
|
+
authorizationCode,
|
|
104
|
+
idToken,
|
|
105
|
+
user,
|
|
106
|
+
email: (_h = (_g = response.user) === null || _g === void 0 ? void 0 : _g.email) !== null && _h !== void 0 ? _h : email,
|
|
107
|
+
givenName,
|
|
108
|
+
familyName,
|
|
109
|
+
};
|
|
110
|
+
if (state !== undefined) {
|
|
111
|
+
result.state = state;
|
|
112
|
+
}
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
decodeJwtPayload(jwt) {
|
|
116
|
+
const parts = jwt.split('.');
|
|
117
|
+
const payload = parts[1];
|
|
118
|
+
const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));
|
|
119
|
+
return JSON.parse(decoded);
|
|
120
|
+
}
|
|
121
|
+
loadScript() {
|
|
122
|
+
if (this.scriptLoaded) {
|
|
123
|
+
return Promise.resolve();
|
|
124
|
+
}
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
const script = document.createElement('script');
|
|
127
|
+
script.src =
|
|
128
|
+
'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';
|
|
129
|
+
script.onload = () => {
|
|
130
|
+
this.scriptLoaded = true;
|
|
131
|
+
resolve();
|
|
132
|
+
};
|
|
133
|
+
script.onerror = () => {
|
|
134
|
+
reject(new Error('Failed to load Apple Sign-In SDK.'));
|
|
135
|
+
};
|
|
136
|
+
document.head.appendChild(script);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
142
|
+
__proto__: null,
|
|
143
|
+
AppleSignInWeb: AppleSignInWeb
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
exports.AppleSignIn = AppleSignIn;
|
|
147
|
+
|
|
148
|
+
return exports;
|
|
149
|
+
|
|
150
|
+
})({}, capacitorExports);
|
|
151
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/definitions.js","esm/index.js","esm/web.js"],"sourcesContent":["/**\n * @since 0.1.0\n */\nexport var SignInScope;\n(function (SignInScope) {\n /**\n * Request the user's email address.\n *\n * @since 0.1.0\n */\n SignInScope[\"Email\"] = \"EMAIL\";\n /**\n * Request the user's full name.\n *\n * @since 0.1.0\n */\n SignInScope[\"FullName\"] = \"FULL_NAME\";\n})(SignInScope || (SignInScope = {}));\n/**\n * @since 0.1.0\n */\nexport var RealUserStatus;\n(function (RealUserStatus) {\n /**\n * The user appears to be a real person.\n *\n * @since 0.1.0\n */\n RealUserStatus[\"LikelyReal\"] = \"LIKELY_REAL\";\n /**\n * The system can't determine whether the user is a real person.\n *\n * @since 0.1.0\n */\n RealUserStatus[\"Unknown\"] = \"UNKNOWN\";\n /**\n * The real user status is not supported on this platform.\n *\n * @since 0.1.0\n */\n RealUserStatus[\"Unsupported\"] = \"UNSUPPORTED\";\n})(RealUserStatus || (RealUserStatus = {}));\n/**\n * @since 0.1.0\n */\nexport var ErrorCode;\n(function (ErrorCode) {\n /**\n * The sign-in was canceled by the user.\n *\n * @since 0.1.0\n */\n ErrorCode[\"SignInCanceled\"] = \"SIGN_IN_CANCELED\";\n})(ErrorCode || (ErrorCode = {}));\n//# sourceMappingURL=definitions.js.map","import { registerPlugin } from '@capacitor/core';\nconst AppleSignIn = registerPlugin('AppleSignIn', {\n web: () => import('./web').then(m => new m.AppleSignInWeb()),\n});\nexport * from './definitions';\nexport { AppleSignIn };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class AppleSignInWeb extends WebPlugin {\n constructor() {\n super(...arguments);\n this.scriptLoaded = false;\n }\n async initialize(options) {\n this.clientId = options.clientId;\n await this.loadScript();\n }\n async signIn(options) {\n var _a, _b, _c, _d, _e, _f, _g, _h;\n if (!this.clientId) {\n throw new Error('clientId must be provided. Call initialize() first.');\n }\n const scope = ((_a = options === null || options === void 0 ? void 0 : options.scopes) !== null && _a !== void 0 ? _a : [])\n .map(s => (s === 'FULL_NAME' ? 'name' : 'email'))\n .join(' ');\n window.AppleID.auth.init({\n clientId: this.clientId,\n scope: scope || undefined,\n redirectURI: options === null || options === void 0 ? void 0 : options.redirectUrl,\n state: options === null || options === void 0 ? void 0 : options.state,\n nonce: options === null || options === void 0 ? void 0 : options.nonce,\n usePopup: true,\n });\n const response = await window.AppleID.auth.signIn();\n const authorization = response.authorization;\n const idToken = authorization.id_token;\n const authorizationCode = authorization.code;\n const state = authorization.state;\n const payload = this.decodeJwtPayload(idToken);\n const user = payload.sub;\n const email = (_b = payload.email) !== null && _b !== void 0 ? _b : null;\n let givenName = null;\n let familyName = null;\n if (response.user) {\n givenName = (_d = (_c = response.user.name) === null || _c === void 0 ? void 0 : _c.firstName) !== null && _d !== void 0 ? _d : null;\n familyName = (_f = (_e = response.user.name) === null || _e === void 0 ? void 0 : _e.lastName) !== null && _f !== void 0 ? _f : null;\n }\n const result = {\n authorizationCode,\n idToken,\n user,\n email: (_h = (_g = response.user) === null || _g === void 0 ? void 0 : _g.email) !== null && _h !== void 0 ? _h : email,\n givenName,\n familyName,\n };\n if (state !== undefined) {\n result.state = state;\n }\n return result;\n }\n decodeJwtPayload(jwt) {\n const parts = jwt.split('.');\n const payload = parts[1];\n const decoded = atob(payload.replace(/-/g, '+').replace(/_/g, '/'));\n return JSON.parse(decoded);\n }\n loadScript() {\n if (this.scriptLoaded) {\n return Promise.resolve();\n }\n return new Promise((resolve, reject) => {\n const script = document.createElement('script');\n script.src =\n 'https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js';\n script.onload = () => {\n this.scriptLoaded = true;\n resolve();\n };\n script.onerror = () => {\n reject(new Error('Failed to load Apple Sign-In SDK.'));\n };\n document.head.appendChild(script);\n });\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["SignInScope","RealUserStatus","ErrorCode","registerPlugin","WebPlugin"],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import AuthenticationServices
|
|
3
|
+
|
|
4
|
+
@objc public class AppleSignIn: NSObject {
|
|
5
|
+
|
|
6
|
+
private var completion: ((_ result: SignInResult?, _ error: Error?) -> Void)?
|
|
7
|
+
|
|
8
|
+
@objc public func signIn(_ options: SignInOptions, presentationContextProvider: ASAuthorizationControllerPresentationContextProviding, completion: @escaping (_ result: SignInResult?, _ error: Error?) -> Void) {
|
|
9
|
+
self.completion = completion
|
|
10
|
+
|
|
11
|
+
let provider = ASAuthorizationAppleIDProvider()
|
|
12
|
+
let request = provider.createRequest()
|
|
13
|
+
if !options.scopes.isEmpty {
|
|
14
|
+
request.requestedScopes = options.scopes
|
|
15
|
+
}
|
|
16
|
+
if let nonce = options.nonce {
|
|
17
|
+
request.nonce = nonce
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
let controller = ASAuthorizationController(authorizationRequests: [request])
|
|
21
|
+
controller.delegate = self
|
|
22
|
+
controller.presentationContextProvider = presentationContextProvider
|
|
23
|
+
controller.performRequests()
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
extension AppleSignIn: ASAuthorizationControllerDelegate {
|
|
28
|
+
public func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
|
|
29
|
+
guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential else {
|
|
30
|
+
completion?(nil, CustomError.signInFailed)
|
|
31
|
+
completion = nil
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
let result = SignInResult(credential: credential)
|
|
35
|
+
completion?(result, nil)
|
|
36
|
+
completion = nil
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
|
|
40
|
+
let asError = error as? ASAuthorizationError
|
|
41
|
+
if asError?.code == .canceled {
|
|
42
|
+
completion?(nil, CustomError.signInCanceled)
|
|
43
|
+
} else {
|
|
44
|
+
completion?(nil, CustomError.signInFailed)
|
|
45
|
+
}
|
|
46
|
+
completion = nil
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
import AuthenticationServices
|
|
4
|
+
|
|
5
|
+
@objc(AppleSignInPlugin)
|
|
6
|
+
public class AppleSignInPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
7
|
+
public let identifier = "AppleSignInPlugin"
|
|
8
|
+
public let jsName = "AppleSignIn"
|
|
9
|
+
public let pluginMethods: [CAPPluginMethod] = [
|
|
10
|
+
CAPPluginMethod(name: "initialize", returnType: CAPPluginReturnPromise),
|
|
11
|
+
CAPPluginMethod(name: "signIn", returnType: CAPPluginReturnPromise)
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
private let tag = "AppleSignIn"
|
|
15
|
+
private var implementation: AppleSignIn?
|
|
16
|
+
|
|
17
|
+
override public func load() {
|
|
18
|
+
self.implementation = AppleSignIn()
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
@objc func initialize(_ call: CAPPluginCall) {
|
|
22
|
+
resolveCall(call)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@objc func signIn(_ call: CAPPluginCall) {
|
|
26
|
+
do {
|
|
27
|
+
let options = try SignInOptions(call)
|
|
28
|
+
|
|
29
|
+
implementation?.signIn(options, presentationContextProvider: self, completion: { result, error in
|
|
30
|
+
if let error = error {
|
|
31
|
+
self.rejectCall(call, error)
|
|
32
|
+
} else {
|
|
33
|
+
self.resolveCall(call, result)
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
} catch {
|
|
37
|
+
rejectCall(call, error)
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private func rejectCall(_ call: CAPPluginCall, _ error: Error) {
|
|
42
|
+
CAPLog.print("[", self.tag, "] ", error)
|
|
43
|
+
var code: String?
|
|
44
|
+
if let customError = error as? CustomError {
|
|
45
|
+
code = customError.code
|
|
46
|
+
}
|
|
47
|
+
call.reject(error.localizedDescription, code)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private func resolveCall(_ call: CAPPluginCall) {
|
|
51
|
+
call.resolve()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private func resolveCall(_ call: CAPPluginCall, _ result: Result?) {
|
|
55
|
+
if let result = result?.toJSObject() as? JSObject {
|
|
56
|
+
call.resolve(result)
|
|
57
|
+
} else {
|
|
58
|
+
call.resolve()
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
extension AppleSignInPlugin: ASAuthorizationControllerPresentationContextProviding {
|
|
64
|
+
public func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
|
|
65
|
+
return self.bridge?.webView?.window ?? ASPresentationAnchor()
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
import AuthenticationServices
|
|
4
|
+
|
|
5
|
+
@objc public class SignInOptions: NSObject {
|
|
6
|
+
let scopes: [ASAuthorization.Scope]
|
|
7
|
+
let nonce: String?
|
|
8
|
+
|
|
9
|
+
init(_ call: CAPPluginCall) throws {
|
|
10
|
+
self.scopes = SignInOptions.getScopesFromCall(call)
|
|
11
|
+
self.nonce = call.getString("nonce")
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
private static func getScopesFromCall(_ call: CAPPluginCall) -> [ASAuthorization.Scope] {
|
|
15
|
+
guard let scopeStrings = call.getArray("scopes") as? [String] else {
|
|
16
|
+
return []
|
|
17
|
+
}
|
|
18
|
+
var scopes: [ASAuthorization.Scope] = []
|
|
19
|
+
for scope in scopeStrings {
|
|
20
|
+
switch scope {
|
|
21
|
+
case "EMAIL":
|
|
22
|
+
scopes.append(.email)
|
|
23
|
+
case "FULL_NAME":
|
|
24
|
+
scopes.append(.fullName)
|
|
25
|
+
default:
|
|
26
|
+
break
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return scopes
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
import AuthenticationServices
|
|
4
|
+
|
|
5
|
+
@objc public class SignInResult: NSObject, Result {
|
|
6
|
+
private let authorizationCode: String
|
|
7
|
+
private let idToken: String
|
|
8
|
+
private let user: String
|
|
9
|
+
private let email: String?
|
|
10
|
+
private let givenName: String?
|
|
11
|
+
private let familyName: String?
|
|
12
|
+
private let realUserStatus: String
|
|
13
|
+
|
|
14
|
+
init(credential: ASAuthorizationAppleIDCredential) {
|
|
15
|
+
self.authorizationCode = String(data: credential.authorizationCode ?? Data(), encoding: .utf8) ?? ""
|
|
16
|
+
self.idToken = String(data: credential.identityToken ?? Data(), encoding: .utf8) ?? ""
|
|
17
|
+
self.user = credential.user
|
|
18
|
+
self.email = credential.email
|
|
19
|
+
self.givenName = credential.fullName?.givenName
|
|
20
|
+
self.familyName = credential.fullName?.familyName
|
|
21
|
+
self.realUserStatus = SignInResult.mapRealUserStatus(credential.realUserStatus)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@objc public func toJSObject() -> AnyObject {
|
|
25
|
+
var result = JSObject()
|
|
26
|
+
result["authorizationCode"] = authorizationCode
|
|
27
|
+
result["idToken"] = idToken
|
|
28
|
+
result["user"] = user
|
|
29
|
+
result["email"] = email == nil ? NSNull() : email
|
|
30
|
+
result["givenName"] = givenName == nil ? NSNull() : givenName
|
|
31
|
+
result["familyName"] = familyName == nil ? NSNull() : familyName
|
|
32
|
+
result["realUserStatus"] = realUserStatus
|
|
33
|
+
return result as AnyObject
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private static func mapRealUserStatus(_ status: ASUserDetectionStatus) -> String {
|
|
37
|
+
switch status {
|
|
38
|
+
case .likelyReal:
|
|
39
|
+
return "LIKELY_REAL"
|
|
40
|
+
case .unknown:
|
|
41
|
+
return "UNKNOWN"
|
|
42
|
+
default:
|
|
43
|
+
return "UNSUPPORTED"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public enum CustomError: Error {
|
|
4
|
+
case signInCanceled
|
|
5
|
+
case signInFailed
|
|
6
|
+
|
|
7
|
+
var code: String? {
|
|
8
|
+
switch self {
|
|
9
|
+
case .signInCanceled:
|
|
10
|
+
return "SIGN_IN_CANCELED"
|
|
11
|
+
case .signInFailed:
|
|
12
|
+
return nil
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
extension CustomError: LocalizedError {
|
|
18
|
+
public var errorDescription: String? {
|
|
19
|
+
switch self {
|
|
20
|
+
case .signInCanceled:
|
|
21
|
+
return NSLocalizedString("Sign in was canceled.", comment: "signInCanceled")
|
|
22
|
+
case .signInFailed:
|
|
23
|
+
return NSLocalizedString("Sign in failed.", comment: "signInFailed")
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|