sign_in_with_apple_user_migrator 1.0.0
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.
- checksums.yaml +7 -0
- data/bin/sign_in_with_apple_user_migrator +6 -0
- data/lib/sign_in_with_apple_user_migrator/access_token_generator.rb +61 -0
- data/lib/sign_in_with_apple_user_migrator/base.rb +36 -0
- data/lib/sign_in_with_apple_user_migrator/cli.rb +111 -0
- data/lib/sign_in_with_apple_user_migrator/client_secret_generator.rb +45 -0
- data/lib/sign_in_with_apple_user_migrator/transfer_id_exchanger.rb +68 -0
- data/lib/sign_in_with_apple_user_migrator/transfer_id_generator.rb +69 -0
- data/lib/sign_in_with_apple_user_migrator/version.rb +3 -0
- data/lib/sign_in_with_apple_user_migrator.rb +9 -0
- metadata +124 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f60fa992a310fa6ba3ebcddb971abb31897d84293702c6f2e14bb6b26663c654
|
4
|
+
data.tar.gz: 498ac47a5d993cf75614c3c1b8278dab75e5fa01cf1d40d6d0a327a00cec1d27
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3731f221c5f566f1b530b2c147d9513e2a3be7220184ad7fe40da162d43c74309097e0b39c0c210cfd0216d5dc11cd973b608e24662749db18bf4c0f75f53364
|
7
|
+
data.tar.gz: 447c998bb2eb493b92632973281626a078ecceb0030e6a6ef8260431858693ab80c6ad09cacfc036918960344941f046a40098d76a13b3069bb7c22e71e165e1
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module SignInWithAppleUserMigrator
|
4
|
+
class AccessTokenGenerator < Base
|
5
|
+
def initialize(client_id:, client_secret:)
|
6
|
+
@client_id = client_id
|
7
|
+
@client_secret = client_secret
|
8
|
+
super()
|
9
|
+
end
|
10
|
+
|
11
|
+
##
|
12
|
+
# Retrieves an access token from Apple's authentication servers
|
13
|
+
#
|
14
|
+
# @param [String] grant_type The type of grant to request (default: 'client_credentials')
|
15
|
+
# @param [String] scope The requested scope for the access token (default: 'user.migration')
|
16
|
+
#
|
17
|
+
# @return [String] The access token string from Apple's authentication server
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# generator = AccessTokenGenerator.new
|
21
|
+
# token = generator.get_access_token
|
22
|
+
# # => "eyJhbGciOiJIUzI1NiIsInR5cCI6Ikp..."
|
23
|
+
#
|
24
|
+
# @raise [StandardError] If the token request fails
|
25
|
+
#
|
26
|
+
def get_access_token(grant_type: 'client_credentials', scope: 'user.migration')
|
27
|
+
logger.debug 'Retrieving access token...'
|
28
|
+
|
29
|
+
uri = URI('https://appleid.apple.com/auth/token')
|
30
|
+
params = {
|
31
|
+
'client_id' => @client_id,
|
32
|
+
'client_secret' => @client_secret,
|
33
|
+
'grant_type' => grant_type,
|
34
|
+
'scope' => scope,
|
35
|
+
}
|
36
|
+
|
37
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
38
|
+
http.use_ssl = true
|
39
|
+
|
40
|
+
request = Net::HTTP::Post.new(uri)
|
41
|
+
request['Content-Type'] = 'application/x-www-form-urlencoded'
|
42
|
+
request.body = URI.encode_www_form(params)
|
43
|
+
|
44
|
+
response = http.request(request)
|
45
|
+
|
46
|
+
if response.code != '200'
|
47
|
+
logger.error "HTTP Status: #{response.code}"
|
48
|
+
logger.error "Response HEADER: #{response.to_hash}"
|
49
|
+
raise AuthorizationError.new <<~LOG
|
50
|
+
Failed to retrieve access token.
|
51
|
+
HTTP Status: #{response.code}
|
52
|
+
Response HEADER: #{response.to_hash}
|
53
|
+
error: #{response.inspect}
|
54
|
+
LOG
|
55
|
+
else
|
56
|
+
logger.debug response.body
|
57
|
+
JSON.parse(response.body)['access_token']
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'jwt'
|
2
|
+
require 'net/http'
|
3
|
+
require 'json'
|
4
|
+
require 'logger'
|
5
|
+
require 'time'
|
6
|
+
|
7
|
+
module SignInWithAppleUserMigrator
|
8
|
+
class AuthorizationError < StandardError; end
|
9
|
+
|
10
|
+
class Base
|
11
|
+
attr_reader :logger
|
12
|
+
|
13
|
+
def initialize()
|
14
|
+
@logger = setup_logger
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def setup_logger
|
19
|
+
logger = Logger.new(STDOUT)
|
20
|
+
log_level = parse_log_level(ENV['LOG_LEVEL'])
|
21
|
+
logger.level = log_level
|
22
|
+
logger
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_log_level(level)
|
26
|
+
case level.to_s.upcase
|
27
|
+
when 'DEBUG' then Logger::DEBUG
|
28
|
+
when 'INFO' then Logger::INFO
|
29
|
+
when 'WARN' then Logger::WARN
|
30
|
+
when 'ERROR' then Logger::ERROR
|
31
|
+
when 'FATAL' then Logger::FATAL
|
32
|
+
else Logger::INFO
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'csv'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'thor'
|
4
|
+
require_relative '../sign_in_with_apple_user_migrator'
|
5
|
+
|
6
|
+
module SignInWithAppleUserMigrator
|
7
|
+
class CLI < Thor
|
8
|
+
desc 'generate_user_transfer_ids', 'Generate user transfer IDs'
|
9
|
+
option :client_id, required: true, desc: 'Client ID'
|
10
|
+
option :key_id, required: true, desc: 'Key ID'
|
11
|
+
option :private_key_path, required: true, desc: 'Private Key Path'
|
12
|
+
option :team_id, required: true, desc: 'Team ID'
|
13
|
+
option :transfer_user_id_csv_path, required: true, desc: 'Transfer User ID CSV Path'
|
14
|
+
option :target_team_id, required: true, desc: 'Target Team ID'
|
15
|
+
|
16
|
+
def generate_user_transfer_ids
|
17
|
+
client_id = options[:client_id]
|
18
|
+
key_id = options[:key_id]
|
19
|
+
private_key_path = options[:private_key_path]
|
20
|
+
team_id = options[:team_id]
|
21
|
+
transfer_user_id_csv_path = options[:transfer_user_id_csv_path]
|
22
|
+
target_team_id = options[:target_team_id]
|
23
|
+
|
24
|
+
client_secret = SignInWithAppleUserMigrator::ClientSecretGenerator.new(
|
25
|
+
client_id: client_id,
|
26
|
+
key_id: key_id,
|
27
|
+
private_key_path: private_key_path,
|
28
|
+
team_id: team_id,
|
29
|
+
).generate_client_secret
|
30
|
+
|
31
|
+
access_token = SignInWithAppleUserMigrator::AccessTokenGenerator.new(
|
32
|
+
client_id: client_id,
|
33
|
+
client_secret: client_secret,
|
34
|
+
).get_access_token
|
35
|
+
|
36
|
+
transfer_id_generator_client = SignInWithAppleUserMigrator::TransferIdGenerator.new(
|
37
|
+
client_id: client_id,
|
38
|
+
client_secret: client_secret,
|
39
|
+
access_token: access_token,
|
40
|
+
target_team_id: target_team_id,
|
41
|
+
)
|
42
|
+
|
43
|
+
FileUtils.mkdir_p('tmp')
|
44
|
+
result_csv_name = "generated_transfer_ids_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"
|
45
|
+
result_path = File.join('tmp', result_csv_name)
|
46
|
+
File.write("tmp/#{result_csv_name}", "user_id,transfer_id,error\n")
|
47
|
+
|
48
|
+
CSV.open(result_path, 'w') do |csv|
|
49
|
+
csv << %w[user_id transfer_id error]
|
50
|
+
|
51
|
+
CSV.foreach(transfer_user_id_csv_path, headers: true) do |row|
|
52
|
+
user_id = row['user_id']
|
53
|
+
next if user_id.nil? || user_id.empty?
|
54
|
+
|
55
|
+
transfer_id, error = transfer_id_generator_client.generate_transfer_id(user_id)
|
56
|
+
csv << [user_id, transfer_id, error]
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
desc 'migrate_user_transfer_ids', 'Migrate user transfer IDs'
|
62
|
+
option :client_id, required: true, desc: 'Client ID'
|
63
|
+
option :key_id, required: true, desc: 'Key ID'
|
64
|
+
option :private_key_path, required: true, desc: 'Private Key Path'
|
65
|
+
option :team_id, required: true, desc: 'Team ID'
|
66
|
+
option :transfer_id_csv_path, required: true, desc: 'Transfer ID CSV Path'
|
67
|
+
|
68
|
+
def migrate_user_transfer_ids
|
69
|
+
client_id = options[:client_id]
|
70
|
+
key_id = options[:key_id]
|
71
|
+
private_key_path = options[:private_key_path]
|
72
|
+
team_id = options[:team_id]
|
73
|
+
transfer_id_csv_path = options[:transfer_id_csv_path]
|
74
|
+
|
75
|
+
client_secret = SignInWithAppleUserMigrator::ClientSecretGenerator.new(
|
76
|
+
client_id: client_id,
|
77
|
+
key_id: key_id,
|
78
|
+
private_key_path: private_key_path,
|
79
|
+
team_id: team_id,
|
80
|
+
).generate_client_secret
|
81
|
+
|
82
|
+
access_token = SignInWithAppleUserMigrator::AccessTokenGenerator.new(
|
83
|
+
client_id: client_id,
|
84
|
+
client_secret: client_secret,
|
85
|
+
).get_access_token
|
86
|
+
|
87
|
+
transfer_id_exchanger_client = SignInWithAppleUserMigrator::TransferIdExchanger.new(
|
88
|
+
client_id: client_id,
|
89
|
+
client_secret: client_secret,
|
90
|
+
access_token: access_token,
|
91
|
+
)
|
92
|
+
|
93
|
+
FileUtils.mkdir_p('tmp')
|
94
|
+
result_csv_name = "exchanged_transfer_ids_#{Time.now.strftime('%Y%m%d%H%M%S')}.csv"
|
95
|
+
result_path = File.join('tmp', result_csv_name)
|
96
|
+
File.write("tmp/#{result_csv_name}", "transfer_id,sub,error\n")
|
97
|
+
|
98
|
+
CSV.open(result_path, 'w') do |csv|
|
99
|
+
csv << %w[transfer_id sub email is_private_email error]
|
100
|
+
|
101
|
+
CSV.foreach(transfer_id_csv_path, headers: true) do |row|
|
102
|
+
transfer_id = row['transfer_id']
|
103
|
+
next if transfer_id.nil? || transfer_id.empty?
|
104
|
+
|
105
|
+
transfer_id, sub, email, is_private_email, error = transfer_id_exchanger_client.migrate(transfer_id)
|
106
|
+
csv << [transfer_id, sub, email, is_private_email, error]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module SignInWithAppleUserMigrator
|
4
|
+
class ClientSecretGenerator < Base
|
5
|
+
def initialize(client_id:, key_id:, private_key_path:, team_id:)
|
6
|
+
@client_id = client_id
|
7
|
+
@key_id = key_id
|
8
|
+
@private_key = File.read(private_key_path)
|
9
|
+
@team_id = team_id
|
10
|
+
super()
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Generates a JSON Web Token (JWT) for Sign in with Apple authentication (client_secret).
|
15
|
+
#
|
16
|
+
# @param [Integer] iat The issued at time (default: current Unix timestamp)
|
17
|
+
# @param [Integer] exp The expiration time (default: current time + 1 hour)
|
18
|
+
#
|
19
|
+
# @return [String] A signed JWT token that can be used as client_secret
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# generator = ClientSecretGenerator.new
|
23
|
+
# jwt = generator.generate_client_secret
|
24
|
+
# # => "eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1..."
|
25
|
+
#
|
26
|
+
# @see https://developer.apple.com/documentation/accountorganizationaldatasharing/creating-a-client-secret
|
27
|
+
#
|
28
|
+
def generate_client_secret(iat: Time.now.to_i, exp: Time.now.to_i + 3600)
|
29
|
+
header = {
|
30
|
+
'kid' => @key_id,
|
31
|
+
'alg' => 'ES256',
|
32
|
+
}
|
33
|
+
|
34
|
+
payload = {
|
35
|
+
'iss' => @team_id,
|
36
|
+
'iat' => iat,
|
37
|
+
'exp' => exp,
|
38
|
+
'aud' => 'https://appleid.apple.com',
|
39
|
+
'sub' => @client_id,
|
40
|
+
}
|
41
|
+
|
42
|
+
JWT.encode(payload, OpenSSL::PKey::EC.new(@private_key), 'ES256', header)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module SignInWithAppleUserMigrator
|
4
|
+
class TransferIdExchanger < Base
|
5
|
+
def initialize(client_id:, client_secret:, access_token:)
|
6
|
+
@client_id = client_id
|
7
|
+
@client_secret = client_secret
|
8
|
+
@access_token = access_token
|
9
|
+
super()
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Exchanges a transfer_id for user information in Sign in with Apple user migration process.
|
14
|
+
#
|
15
|
+
# @param transfer_id [String] The transfer_id obtained from the source team
|
16
|
+
#
|
17
|
+
# @return [Array<String, String, String, Boolean, String>]
|
18
|
+
# Success: [transfer_id, sub, email, is_private_email, nil]
|
19
|
+
# Failure: [transfer_id, nil, nil, nil, error_message]
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# exchanger = TransferIdExchanger.new(
|
23
|
+
# client_id: 'your_client_id',
|
24
|
+
# client_secret: 'your_client_secret',
|
25
|
+
# access_token: 'your_access_token'
|
26
|
+
# )
|
27
|
+
# transfer_id, sub, email, is_private_email, error = exchanger.migrate('transfer_id')
|
28
|
+
#
|
29
|
+
# @raise [JSON::ParserError] When JSON parsing of response fails
|
30
|
+
#
|
31
|
+
# @see https://developer.apple.com/documentation/sign_in_with_apple/transferring_your_apps_and_users_to_another_team
|
32
|
+
#
|
33
|
+
def migrate(transfer_id)
|
34
|
+
logger.debug "Migrate transfer_id for #{transfer_id}"
|
35
|
+
|
36
|
+
request_data = {
|
37
|
+
'transfer_sub' => transfer_id,
|
38
|
+
'client_id' => @client_id,
|
39
|
+
'client_secret' => @client_secret,
|
40
|
+
}
|
41
|
+
|
42
|
+
uri = URI('https://appleid.apple.com/auth/usermigrationinfo')
|
43
|
+
request = Net::HTTP::Post.new(uri)
|
44
|
+
request['Content-Type'] = 'application/x-www-form-urlencoded'
|
45
|
+
request['Authorization'] = "Bearer #{@access_token}"
|
46
|
+
|
47
|
+
request.body = URI.encode_www_form(request_data)
|
48
|
+
|
49
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
50
|
+
http.request(request)
|
51
|
+
end
|
52
|
+
|
53
|
+
result = JSON.parse(response.body)
|
54
|
+
|
55
|
+
if result['error']
|
56
|
+
error_message = "HTTP Status: #{response.code}, Error: #{result.inspect}"
|
57
|
+
logger.error "Failed to exchange transfer_id: #{error_message}"
|
58
|
+
return [transfer_id, nil, nil, nil, error_message]
|
59
|
+
end
|
60
|
+
|
61
|
+
sub = result['sub']
|
62
|
+
email = result['email']
|
63
|
+
is_private_email = result['is_private_email']
|
64
|
+
logger.info "Success to migrate sub: #{transfer_id}"
|
65
|
+
[transfer_id, sub, email, is_private_email, nil]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require_relative 'base'
|
2
|
+
|
3
|
+
module SignInWithAppleUserMigrator
|
4
|
+
class TransferIdGenerator < Base
|
5
|
+
def initialize(client_id:, client_secret:, access_token:, target_team_id:)
|
6
|
+
@client_id = client_id
|
7
|
+
@client_secret = client_secret
|
8
|
+
@target_team_id = target_team_id
|
9
|
+
@access_token = access_token
|
10
|
+
super()
|
11
|
+
end
|
12
|
+
|
13
|
+
##
|
14
|
+
# Generates transfer_id required for Sign in with Apple user migration.
|
15
|
+
#
|
16
|
+
# @param sub [String] The user identifier (sub) from Sign in with Apple
|
17
|
+
#
|
18
|
+
# @return [Array<String, String>]
|
19
|
+
# Success: [transfer_id, nil]
|
20
|
+
# Failure: [nil, error_message]
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# generator = TransferIdGenerator.new(
|
24
|
+
# client_id: 'your_client_id',
|
25
|
+
# client_secret: 'your_client_secret',
|
26
|
+
# access_token: 'your_access_token',
|
27
|
+
# target_team_id: 'target_team_id'
|
28
|
+
# )
|
29
|
+
# transfer_id, error = generator.generate_transfer_id('user_sub')
|
30
|
+
#
|
31
|
+
# @raise [JSON::ParserError] When JSON parsing of response fails
|
32
|
+
#
|
33
|
+
# @see https://developer.apple.com/documentation/sign_in_with_apple/transferring_your_apps_and_users_to_another_team
|
34
|
+
#
|
35
|
+
def generate_transfer_id(sub)
|
36
|
+
logger.debug "Generated transfer_id for #{sub}"
|
37
|
+
|
38
|
+
request_data = {
|
39
|
+
'sub' => sub,
|
40
|
+
'target' => @target_team_id,
|
41
|
+
'client_id' => @client_id,
|
42
|
+
'client_secret' => @client_secret,
|
43
|
+
}
|
44
|
+
|
45
|
+
uri = URI('https://appleid.apple.com/auth/usermigrationinfo')
|
46
|
+
request = Net::HTTP::Post.new(uri)
|
47
|
+
request['Content-Type'] = 'application/x-www-form-urlencoded'
|
48
|
+
request['Authorization'] = "Bearer #{@access_token}"
|
49
|
+
|
50
|
+
request.body = URI.encode_www_form(request_data)
|
51
|
+
|
52
|
+
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
|
53
|
+
http.request(request)
|
54
|
+
end
|
55
|
+
|
56
|
+
result = JSON.parse(response.body)
|
57
|
+
|
58
|
+
if result['error']
|
59
|
+
error_message = "HTTP Status: #{response.code}, Error: #{result.inspect}"
|
60
|
+
logger.error "Failed to generate transfer_id: #{error_message}"
|
61
|
+
return [nil, error_message]
|
62
|
+
end
|
63
|
+
|
64
|
+
transfer_id = result['transfer_sub']
|
65
|
+
logger.info "Success to generate transfer_id: #{transfer_id}"
|
66
|
+
[transfer_id, nil]
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require_relative 'sign_in_with_apple_user_migrator/access_token_generator'
|
2
|
+
require_relative 'sign_in_with_apple_user_migrator/cli'
|
3
|
+
require_relative 'sign_in_with_apple_user_migrator/client_secret_generator'
|
4
|
+
require_relative 'sign_in_with_apple_user_migrator/transfer_id_exchanger'
|
5
|
+
require_relative 'sign_in_with_apple_user_migrator/transfer_id_generator'
|
6
|
+
require_relative 'sign_in_with_apple_user_migrator/version'
|
7
|
+
|
8
|
+
module SignInWithAppleUserMigrator
|
9
|
+
end
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sign_in_with_apple_user_migrator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- sakurahigashi2
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2025-01-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: thor
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: jwt
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '13'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: webmock
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3'
|
83
|
+
description: Tool for migrating Apple Sign In users between teams
|
84
|
+
email:
|
85
|
+
- joh.murata@gmail.com
|
86
|
+
executables:
|
87
|
+
- sign_in_with_apple_user_migrator
|
88
|
+
extensions: []
|
89
|
+
extra_rdoc_files: []
|
90
|
+
files:
|
91
|
+
- bin/sign_in_with_apple_user_migrator
|
92
|
+
- lib/sign_in_with_apple_user_migrator.rb
|
93
|
+
- lib/sign_in_with_apple_user_migrator/access_token_generator.rb
|
94
|
+
- lib/sign_in_with_apple_user_migrator/base.rb
|
95
|
+
- lib/sign_in_with_apple_user_migrator/cli.rb
|
96
|
+
- lib/sign_in_with_apple_user_migrator/client_secret_generator.rb
|
97
|
+
- lib/sign_in_with_apple_user_migrator/transfer_id_exchanger.rb
|
98
|
+
- lib/sign_in_with_apple_user_migrator/transfer_id_generator.rb
|
99
|
+
- lib/sign_in_with_apple_user_migrator/version.rb
|
100
|
+
homepage: https://github.com/sakurahigashi2/sign_in_with_apple_user_migrator
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata:
|
104
|
+
documentation_uri: https://github.com/sakurahigashi2/sign_in_with_apple_user_migrator
|
105
|
+
post_install_message:
|
106
|
+
rdoc_options: []
|
107
|
+
require_paths:
|
108
|
+
- lib
|
109
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: 2.5.0
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
requirements: []
|
120
|
+
rubygems_version: 3.4.10
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: Apple Sign In User Migration Tool
|
124
|
+
test_files: []
|